T
TanStack•5mo ago
genetic-orange

What's the point of ensureQueryData in RQ examples

Like here: https://tanstack.com/start/latest/docs/framework/react/examples/start-basic-react-query?path=examples%2Freact%2Fstart-basic-react-query%2Fsrc%2Froutes%2Fusers.%24userId.tsx First the loader does this:
loader: async ({ context, params: { userId } }) => {
await context.queryClient.ensureQueryData(userQueryOptions(userId))
},
loader: async ({ context, params: { userId } }) => {
await context.queryClient.ensureQueryData(userQueryOptions(userId))
},
And then in the component:
const userQuery = useSuspenseQuery(userQueryOptions(params.userId))
const userQuery = useSuspenseQuery(userQueryOptions(params.userId))
Wouldn't useSuspenseQuery be enough?
React TanStack Start Start Basic React Query Example | TanStack Sta...
An example showing how to implement Start Basic React Query in React using TanStack Start.
15 Replies
genetic-orange
genetic-orangeOP•5mo ago
React TanStack Start Start Basic React Query Example | TanStack Sta...
An example showing how to implement Start Basic React Query in React using TanStack Start.
ratty-blush
ratty-blush•5mo ago
it's to enable data preloading upon link hover wouldn't have to be returned just awaited
genetic-orange
genetic-orangeOP•5mo ago
Oh. That makes sense. Thank you! Doesn't ensureQueryData throw on error? How does that work if you preload upon hover and don't navigate yet? I see you use prefetchQueryData in the deferred example.
ratty-blush
ratty-blush•5mo ago
why should it throw?
genetic-orange
genetic-orangeOP•5mo ago
https://tanstack.com/query/latest/docs/reference/QueryClient/#queryclientensurequerydata Because it runs fetchQuery if there's nothing in the cache, and:
fetchQuery is an asynchronous method that can be used to fetch and cache a query. It will either resolve with the data or throw with the error.
But maybe I'm misunderstanding what this line says:
If the query does not exist, queryClient.fetchQuery will be called and its results returned.
Maybe it only returns data without throwing on error. It seems like it would throw: https://github.com/TanStack/query/blob/256624af671772732c7e11c2689bb1697ee7e72c/packages/query-core/src/queryClient.ts#L154
ratty-blush
ratty-blush•5mo ago
probably not an issue though if it fails to preload, then router knows that this route is not preloaded
genetic-orange
genetic-orangeOP•5mo ago
rival-black
rival-black•4mo ago
I have another question related to this - if ensureQueryData fails to get cached data it will call a fetch in the loader right? Then would useSuspenseQuery fetch again? because by default staletime is 0
ratty-blush
ratty-blush•4mo ago
which staleTime is 0? router or query
rival-black
rival-black•4mo ago
query query default stale time is 0 - so my understanding is that ensureQueryData and useSuspenseQuery in the same route will cause a fetch twice when the route is visited
ratty-blush
ratty-blush•4mo ago
@TkDodo 🔮 can you have a look please?
itchy-amethyst
itchy-amethyst•4mo ago
Suspense gets a minimal staleTime set internally so you should only see one fetch If the loader fails the component has to fetch again because it needs data and there's nothing there yet. That is independent of staleTime
rival-black
rival-black•4w ago
Sorry what i meant was - ensureQueryData will fetch the data and that would have a default stale time of 0 from my understanding. So when useQuery or useSuspenseQuery comes around, would it cause a fetch again? Presumably because useQuery and useSuspenseQuery execute after ensureQueryData and by then the data is already "stale"
itchy-amethyst
itchy-amethyst•4w ago
Yes, so set a staleTime. Same as with SSR or any prefetching really
rival-black
rival-black•4w ago
Thanks for explaining!

Did you find this page helpful?