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