Learn how to fetch data asynchronously in Next.js using server actions and react query
In Nextbase starter kit, we to rely on server components as much as possible to fetch data. The advantages are
smaller bundle sizes: because we don't have to ship the data fetching logic to the client
faster page loads: because we rely on the cpu power of the server instead of the client to fetch data. Server CPUs are usually faster than client CPUs.
Since server components can by async, we can just await on the data which we require for that component. Next.js layouts and pages are server components
by default unless you explicitly specify them as client components.
For instance, take a look at our the page rendering our /blog/[slug] route:
Notice how we are awaiting on the anonGetPublishedBlogPostBySlug function to fetch the blog post data. This function is a server action which is defined in src/data/anon/internalBlog.ts. And since the BlogPostPage is a server component, we can await on the data fetching function.
Server components have the added benefit of streaming rendering. Consider the page responsible for rendering the blog list page at /blog. This page has to fetch two sets of data: the list of blog posts and the list of tags. We can fetch both of these data sets in parallel and stream the rendering of the page as soon as the data is available.
In this case, we have moved the data fetching into two separate components: Tags and BlogList.
Both of these components are server components and since they are wrapped in Suspense they can be rendered in parallel.
Also, the page does not have to wait for the data to be fetched before it starts rendering. It can start rendering and render the child components as soon as the data is available.
So the user experience for this page looks like this:
the page starts rendering
"All blog posts" title is rendered
"Loading tags..." is rendered and when the tags are fetched, the tags are rendered
"Loading posts..." is rendered and when the posts are fetched, the posts are rendered
This is a much better user experience than having to wait for the page to render until all the data is fetched.
We don't fetching data much in client components unless in very rare cases. To fetch data in client components simply rely on useQuery from
react-query. For eg: the login button in the navigation menu is a client component and it fetches the user data using useQuery: