T
TanStack•8mo ago
ratty-blush

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
ratty-blush
ratty-blushOP•8mo 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.
national-gold
national-gold•8mo ago
it's to enable data preloading upon link hover wouldn't have to be returned just awaited
ratty-blush
ratty-blushOP•8mo 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.
national-gold
national-gold•8mo ago
why should it throw?
ratty-blush
ratty-blushOP•8mo 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
national-gold
national-gold•8mo ago
probably not an issue though if it fails to preload, then router knows that this route is not preloaded
ratty-blush
ratty-blushOP•8mo ago
optimistic-gold
optimistic-gold•7mo 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
national-gold
national-gold•7mo ago
which staleTime is 0? router or query
optimistic-gold
optimistic-gold•7mo 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
national-gold
national-gold•7mo ago
@TkDodo 🔮 can you have a look please?
ambitious-aqua
ambitious-aqua•7mo 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
optimistic-gold
optimistic-gold•4mo 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"
ambitious-aqua
ambitious-aqua•4mo ago
Yes, so set a staleTime. Same as with SSR or any prefetching really
optimistic-gold
optimistic-gold•4mo ago
Thanks for explaining!

Did you find this page helpful?