T
TanStack16mo ago
wise-white

I don't know if I'm misunderstanding streaming?

(I'm using next.js 14 app router) So I'm just trying to experiment around, and I can't really get streaming to work, like Suspsense. It just never says Loading... This is my page.tsx:
export default function StreamingTestQuery() {
const queryClient = getQueryClient();

void queryClient.prefetchQuery<PlayerCountType[]>({
queryKey: ["playerCount"],
queryFn: () => getPlayerCount(),
});

return (
<div>
<h1>Streaming Test with React Query</h1>
<HydrationBoundary state={dehydrate(queryClient)}>
<PostFeedQuery />
</HydrationBoundary>
</div>
);
}
export default function StreamingTestQuery() {
const queryClient = getQueryClient();

void queryClient.prefetchQuery<PlayerCountType[]>({
queryKey: ["playerCount"],
queryFn: () => getPlayerCount(),
});

return (
<div>
<h1>Streaming Test with React Query</h1>
<HydrationBoundary state={dehydrate(queryClient)}>
<PostFeedQuery />
</HydrationBoundary>
</div>
);
}
And from what i could understand, this should render instantly, since there's no async work, and the promise gets put into the QueryCache. But it dosen't render instantly. This is PostFeedQuery.tsx:
const PostFeed: FC<PostFeedProps> = ({}) => {
const { data: playerCount, isLoading } = useSuspenseQuery({
queryKey: ["playerCount"],
queryFn: () => getPlayerCount(),
});

console.log(isLoading); // Always false
if (isLoading) {
return <div>Loading...</div>;
}
const PostFeed: FC<PostFeedProps> = ({}) => {
const { data: playerCount, isLoading } = useSuspenseQuery({
queryKey: ["playerCount"],
queryFn: () => getPlayerCount(),
});

console.log(isLoading); // Always false
if (isLoading) {
return <div>Loading...</div>;
}
7 Replies
wise-white
wise-whiteOP16mo ago
Hope someone could explain a bit further
afraid-scarlet
afraid-scarlet16mo ago
because with suspense, isLoading is always false because it will bubble up to the nearest suspense boundary Wrap your component in a suspense boundary or create a loading.tsx or something like that so next creates one for you the point of suspense is (in part) that you don't have to write if loading and if error checks anymore
wise-white
wise-whiteOP16mo ago
So isLoading would never really be used with useSuspenseQuery? This seems to work, don't know if you meant this:
return (
<div>
<h1>Streaming Test with React Query</h1>
<Suspense fallback={<p>Loading...</p>}>
<HydrationBoundary state={dehydrate(queryClient)}>
<PostFeedQuery />
</HydrationBoundary>
</Suspense>
</div>
);
return (
<div>
<h1>Streaming Test with React Query</h1>
<Suspense fallback={<p>Loading...</p>}>
<HydrationBoundary state={dehydrate(queryClient)}>
<PostFeedQuery />
</HydrationBoundary>
</Suspense>
</div>
);
afraid-scarlet
afraid-scarlet16mo ago
yes
wise-white
wise-whiteOP16mo ago
I'm pretty new to TanStack Query, but what would be the point of using it, in this scenario. Couldn't you just pass the data down? Does it have to do with error handling, cache, or other functionality that's under the hood?
other-emerald
other-emerald16mo ago
you can just pass the data down, but by using useSuspenseQuery, your component can focus on rendering the success state of your data-fetching. Then you have the Suspense react primitive to handle the loading state and an ErrorBoundary component to handle the error state
wise-white
wise-whiteOP16mo ago
I don't really understand that. If I pass it down, then the component will already have the data, and would focus on rendering the success state as much as useSuspenseQuery. Or? I just saw there was the experimental ReactQueryStreamedHydration, and by my undestanding, I will just be able to remove all of my prefetching, and it will still fetch it on the server. Am I understanding it correctly?

Did you find this page helpful?