Reputation: 7543
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
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:
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
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
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