(Edited to clarify the question)
Q. why does queryClient.prefetchQuery()
not request on the server but on the client?
In Nextjs14, the queryClient.prefetchQuery()
seems to fetch the request on the client. When I open up the network tab, I see it requesting, and the isLoading
state also starts from false
to true
.
simplified code:
export const getUserArticles = async ({ page, userId }: { userId: number; page: number }) => {
const response = await httpClient.get<{ message: string; result: any[] }>(
`/api/users/${userId}/articles?page=${page}`
)
return response.data?.result || []
}
export const ARTICLES_QUERY_KEYS = {
all: ['articles'] as const,
getUserArticles: (userId: number, page: number) => ['user-articles', userId, page] as const,
}
export const useGetUserArticlesQuery = ({
userId,
page = 1,
}: {
page: number
userId: (typeof user.$inferSelect)['id']
}) => {
return useQuery({
queryKey: ARTICLES_QUERY_KEYS.getUserArticles(userId, page),
queryFn: () => getUserArticles({ userId, page }),
refetchOnMount: false,
refetchOnWindowFocus: false,
})
}
page.tsx
export default async function Page({ params: { id: pageUserId }, searchParams: { page = '1' } }: PageProps) {
const { user: loginUser } = await getUser()
const queryClient = new QueryClient()
await queryClient.prefetchQuery({
queryKey: ARTICLES_QUERY_KEYS.getUserArticles(+pageUserId, +page),
queryFn: () => getUserArticles({ userId: +pageUserId, page: +page }),
})
return (
<Card size="2" variant="ghost">
<Heading as="h2" size="6" mb="8">
articles
</Heading>
<HydrationBoundary state={dehydrate(queryClient)}>
<Articles />
</HydrationBoundary>
</Card>
)
articles.tsx
'use client'
export default function Articles() {
const { data: articles } = useGetUserArticlesQuery({ userId: 1, page: 1 })
// this condition works. which I believe shouldn't work.
if (isLoading) {
return <div>loading...</div>
}
return (
<Flex direction="column" gap="4" mb="2">
{articles?.map((post) => (
<Flex justify="between" key={post.id}>
<Box>
<Link
href={`/articles/${post.id}`}
size="4"
weight="medium"
highContrast
underline="hover"
style={{ wordBreak: 'keep-all' }}
>
{post.title} ({post.comments})
</Link>
<Text as="div" size="2" mb="1" color="gray">
{post.preview}
</Text>
<Flex align="center" gap="2">
<Text as="div" size="1" color="gray">
{post.nickname} | {post.likes}
</Text>
</Flex>
</Box>
</Flex>
))}
</Flex>
)
}
for the queryClient setup, I followed https://tanstack.com/query/latest/docs/framework/react/guides/advanced-ssr#initial-setup
1