Wordpressor
Wordpressor

Reputation: 7543

Preloading getServerSideProps data with Next.js?

I've got a simple React component:

const Page = ({ data }) => {
    return (
        <header>
        {data.length !== 0 ?
          <>
            {data((d) =>
              // render data
            )}
          </>
          :
          <>Loading...</>
        }
        </header>
      )
    }

I'm getting the data using Next.js recommended getServerSideProps:

export async function getServerSideProps() {
  // Fetch data from external API
  const res = await fetch(`someurl`)
  const data = await res.json()

  // Pass data to the page via props
  return { props: { data } }
}

Now, for the love of God, I can't figure out why <>Loading...</> is never rendering. The page is blank and then everything pops up. Why does it happen and how do I fix that? of course data.length IS 0 before it's fetched...

Note I'm using dynamic routing and do not want to go with getStaticProps.

Upvotes: 5

Views: 17398

Answers (3)

ZiiMakc
ZiiMakc

Reputation: 36826

It's obvious that user should not wait a few seconds in which nothing happens (because getServerSideProps is not finished loading) when he clicks a link. He should see some action is happening, for example:

  • Loading spinner
  • Data template (boxes for images, text and so on), youtube example.

But for now it's not possible with getServerSideProps, because page is rendered only after getServerSideProps request is complete.

There is exist future request on next.js about this, so i hope it will be implemented.

Upvotes: 2

dna
dna

Reputation: 2307

getServerSideProps always runs on server side also for client side navigation.

When you return data from getServerSideProps (if the fetch method is executed without errors) it will have always return a value.

In your example <Loading /> will be visible only if data returned from fetch has 0 length and will never be visible during fetch.

Here the docs https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering

Upvotes: 5

Vibhav
Vibhav

Reputation: 321

you need to use isFallback method provided by there next/router. have a look on this code try to look for isfallback https://github.com/vercel/next-site/blob/master/pages/docs/%5B%5B...slug%5D%5D.js.

Edit: 

`export async function getServerSideProps() {
  Fetch data from external API
  const res = await fetch(someurl)
  const data = await res.json()

   Pass data to the page via props
  return {
        props: res ? {
            data,
            id,
            url,
        } : {}
    };
}
`


and in your component

    const router = useRouter();
    const { isFallback } = router
    if (isFallback) {
        return <Loading />
    }
    else {
        return (
            // render data
        )
    }

Upvotes: -1

Related Questions