-
|
Hello, I’m learning TanStack Query. Situation:
Question: Relevant Code: page.tsx client component queryOptions ServerFetchBoundary.tsx queryClientOption Is there a recommended way to handle prefetchInfiniteQuery in Server Components so that the client can safely continue infiniteQuery fetching even when the server throws an error? Thank you for your help! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
|
streaming doesn’t yet work with infinite queries: |
Beta Was this translation helpful? Give feedback.
-
|
The root cause here is that your Here's what happens step by step:
The fix: await your prefetches and catch auth failures Update export const ServerFetchBoundary = async ({
children,
queryOptions,
infiniteQueryOptions,
}: ServerFetchBoundaryProps) => {
await connection();
const queryClient = getQueryClient();
const queries = queryOptions
? Array.isArray(queryOptions) ? queryOptions : [queryOptions]
: [];
const infiniteQueries = infiniteQueryOptions
? Array.isArray(infiniteQueryOptions) ? infiniteQueryOptions : [infiniteQueryOptions]
: [];
await Promise.all([
...queries.map(opt => queryClient.prefetchQuery(opt).catch(() => {})),
...infiniteQueries.map(opt => queryClient.prefetchInfiniteQuery(opt).catch(() => {})),
]);
return <HydrationBoundary state={dehydrate(queryClient)}>{children}</HydrationBoundary>;
};The
This avoids the streaming path entirely for all these queries, which is exactly TkDodo's recommended workaround: "don't stream promises for infinite queries, but await them on the server." Why not just make getNextPageParam: (lastPage: FeedListResponse | undefined) =>
lastPage?.hasNext ? lastPage.cursor : undefined,This silences the crash but doesn't fix the underlying data structure problem — the client is still working with a malformed query state that'll cause other subtle issues. The upstream fix for the streaming case is being tracked in PR #9633 if you need that path later. |
Beta Was this translation helpful? Give feedback.
-
Resolving the
|
Beta Was this translation helpful? Give feedback.
The root cause here is that your
ServerFetchBoundaryisn't awaiting the prefetches, which triggers the streaming path that's broken for infinite queries (the bug TkDodo linked).Here's what happens step by step:
infiniteQueries.forEach(opt => queryClient.prefetchInfiniteQuery(opt))fires the prefetch but doesn't await it, so the query stays inpendingstate whendehydrate(queryClient)runs|| query.state.status === 'pending'inshouldDehydrateQuery, the pending promise gets dehydrated and sent to the clientquery.fetch(undefined, { initialPromise })to pick up the stream — but critically, it does not attachinfiniteQueryBehaviorbecause hyd…