TanStackT
TanStack7mo ago
4 replies
clean-aquamarine

Router + Query + Suspense + Deferred data

Hello,
I have a question about using Router + Query + Suspense + deferred data preload
So I want to have a page with a critical data + deferred data (preferrably, multiple ones) while using Tanstack Query.

It seems like the flow should be something like that:
- User make a request, server runs loader that includes both critical data fetches and deferred data fetches
- As long as critical data is retrieved, loaders returns with { deferred: queryClient.fetchQuery(...) }
- Critical data is dehydrated (queryClient dehydrates completely) on server and hydrated on client (via createTanStackRouter.(de)hydrate functions)
- Now, deferred data is delivered later, in a promise and client has to hydrate to the query client manually

Basically, route looks like this:
const Route = createFileRoute("...")({
  // ...
    loader: async ({ context }) => {
    const deferredDataPromise = context.queryClient.prefetchQuery(deferredQueryOptions());
    const criticalData = await context.queryClient.fetchQuery(criticalQueryOptions());
    return {
      deferred: deferredDataPromise,
    };
    },
});


The problem is how to hydrate deferred data properly on the client. The way I made it work is:
const loaderData = Route.useLoaderData();
const deferredData = React.use(loaderData.deferred);
const query = useSuspenseQuery({ ...deferredQueryOptions(), initialData: deferredData });

That's not ideal, I'd like to have just the last string and don't drill props if I need deferred data deeper in the tree.
Was this page helpful?