#Router + Query + Suspense + Deferred data

4 messages · Page 1 of 1 (latest)

eager thicket
#

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.

#

One might expect route itself would have dehydrate / hydrate parameters that will run server / client-side respectively.

createFileRoute('...')({
  dehydrate: ({ context }, { chunk }) => ({ dehydratedState: context.queryClient.dehydrate({...}) }),
  hydrate: ({ context }, { dehydratedState }) => context.queryClient.hydrate(dehydratedState),
})

In this case the main problem is how to signal useSuspenseQuery that we need to await given promise (should initialData have an option to be a promise for useSuspenseQuery?)

median pulsar
#

we have a package for that

#

@tanstack/react-router-with-query