I’m working on my Next.js project with a server component page where I’m prefetching posts with HydrationBoundary. Here’s the server component:
'use server';
import PostList from '@/components/shared/PostList/PostList';
import SomethingWentWrong from '@/components/shared/SomethingWentWrong/SomethingWentWrong';
import { QueryClient, HydrationBoundary, dehydrate } from '@tanstack/react-query';
import { getPosts } from '@/actions/posts';
const Page = async () => {
try {
const queryClient = new QueryClient();
await queryClient.prefetchQuery({
queryKey: ['posts'],
queryFn: () => getPosts(),
});
return (
<section>
<HydrationBoundary state={dehydrate(queryClient)}>
<PostList />
</HydrationBoundary>
</section>
);
} catch (error) {
return (
<section>
<SomethingWentWrong />
</section>
);
}
};
export default Page;
After the initial prefetch, the data is cached, and I can see my posts without any delay:
'use client';
import React from 'react';
// components
import Post from '@/components/shared/Post/Post';
// utils
import { commentsCount } from '@/utils/comments';
// actions
import { getPosts } from '@/actions/posts';
// react-query
import { useSuspenseQuery } from '@tanstack/react-query';
const PostList = () => {
const {
data,
error: postError,
fetchStatus,
} = useSuspenseQuery({
queryFn: getPosts,
queryKey: ['posts'],
});
return (
<>
{data?.posts &&
data.posts.map((post) => (
<Post
key={post._id}
id={post._id}
classNames={'[&:not(:last-child)]:mb-4'}
title={post.title}
description={post.description}
image={post.image}
createdAt={post.createdAt}
tags={post.tags}
viewsCount={post.viewsCount}
author={post.author}
likesCount={post.likes}
commentsCount={commentsCount(post.comments)}
/>
))}
</>
);
};
export default PostList;
When I hard refresh the page, prefetching takes about 4 seconds to load the data, and during this time, it shows a blank page and doesn’t even display the header which is included in the layout.
Is there a way to show a <Suspense fallback={…}></Suspense> while the data is being prefetched?