What does the `@tanstack/react-query-next-experimental` package do exactly?
From the docs:
This package will allow you to fetch data on the server (in a Client Component) by just callingThe statement above is under the headinguseSuspenseQuery
in your component. Results will then be streamed from the server to the client as SuspenseBoundaries resolve. If you calluseSuspenseQuery
without wrapping it in a<Suspense>
boundary, the HTML response won't start until the fetch resolves. This can be when you want depending on the situation, but keep in mind that this will hurt your TTFB.
Experimental streaming without prefetching in Next.js
on the Advanced SSR page. My first question is,
- Is there a difference in the behaviour of useSuspenseQuery
when data is prefetched vs when data isn't?
Without any additional setup, I would expect useSuspenseQuery
to just trigger suspense, and cause the parent tree (up to the closest <Suspense>
if any) to suspend, while not affecting streaming of other streamable parts.
I tried this by modifying the streaming suspense example and everything seems to work fine. The original example is at: https://tanstack.com/query/latest/docs/framework/react/examples/nextjs-suspense-streaming
(Note that the example as embedded on this page uses StackBlitz, which causes an error. You can access the example on codesandbox here: https://codesandbox.io/p/devbox/github/tanstack/query/tree/main/examples/react/nextjs-suspense-streaming)
Here's my modified CodeSandbox: https://codesandbox.io/p/devbox/serene-leakey-dcvpmx
This modified version simply removes the ReactQueryStreamedHydration
used to wrap the app in providers.tsx
. With this removal, everything still seems to still work fine. The parts wrapped in suspense are still streamed normally without prefetching. My second question is:
- What is the purpose of @tanstack/react-query-next-experimental
, and in particular, the ReactQueryStreamedHydration
component?3 Replies
environmental-roseOP•13mo ago
When I remove the
<Suspense>
around any of the wrapped components, everything works fine too, without the ReactQueryStreamedHydration
component (no HTML is returned until the component resolves), which is what I expect.continuing-cyan•13mo ago
"everything works fine" is not entirely true because the data that is fetched on the server never winds up in the client side cache without the plugin.
you will see the result on the screen because it "renders" to html, but it won't be in the client side cache. The query devtools should show that
environmental-roseOP•13mo ago
Thanks. I just read through the source. It looks like the
ReactQueryStreamedHydration
is just making the data available on the client by storing it on window
via a custom script tag inserted with useServerInsertedHTML
.
One more thing though. I was expecting that the rendered HTML would be immediately overridden by the fallback on the client since useSuspenseQuery
will trigger suspense on the client (when not using the ReactQueryStreamedHydration
component). However, if the suspending component results in the same value as the server-rendered HTML (probably not the best way to put it), then the fallback isn't rendered. For example, given the following:
On the client, the fallback is first rendered, then the server-rendered HTML (very briefly), and then the fallback is rendered again, and then the HTML is rendered when the fetch is completed on the client, which I believe is because of the Math.random()
. If I remove the random part, then the fallback is not re-rendered when the query is fetching on the client. This is a React thing, right?