T
TanStack3mo ago
foreign-sapphire

Fetching multiple resources in Loader using ensureQueryData

I had a question about handling multiple data fetches in a loader using ensureQueryData. I followed the example from the docs and added another queryOptions for a second fetch. Is this the recommended approach?
// src/routes/posts.tsx

const postsQueryOptions = queryOptions({
queryKey: ['posts'],
queryFn: () => fetchPosts(),
})

const userQueryOptions = queryOptions({
queryKey: ['user'],
queryFn: () => fetchUser(),
})

export const Route = createFileRoute({
loader: async () => {
await Promise.all([
queryClient.ensureQueryData(postsQueryOptions),
queryClient.ensureQueryData(userQueryOptions),
])
},
component: () => {
const { data: posts } = useSuspenseQuery(postsQueryOptions)
const { data: user } = useSuspenseQuery(userQueryOptions)

return (
<div>
{posts.map((post) => (
<Post key={post.id} post={post} />
))}
</div>
)
},
})
// src/routes/posts.tsx

const postsQueryOptions = queryOptions({
queryKey: ['posts'],
queryFn: () => fetchPosts(),
})

const userQueryOptions = queryOptions({
queryKey: ['user'],
queryFn: () => fetchUser(),
})

export const Route = createFileRoute({
loader: async () => {
await Promise.all([
queryClient.ensureQueryData(postsQueryOptions),
queryClient.ensureQueryData(userQueryOptions),
])
},
component: () => {
const { data: posts } = useSuspenseQuery(postsQueryOptions)
const { data: user } = useSuspenseQuery(userQueryOptions)

return (
<div>
{posts.map((post) => (
<Post key={post.id} post={post} />
))}
</div>
)
},
})
3 Replies
ratty-blush
ratty-blush3mo ago
looks ok to me
sunny-green
sunny-green3mo ago
What is difference between ensureQueryData vs. preferchQuery?
adverse-sapphire
adverse-sapphire3mo ago
ensureQueryData is similar to fetch, in that it actually returns data. ensureQueryData will do the following: A) if there is no cached data, then it will call the queryFn and return the response (throwing an error if the query fails) B) if there is cached data and the stale time is not met, it will return the data C) If there is cached data and the stale time has passed, then it will immediately return the data, and then request new data in the background On the other hand, prefetch never returns data and will not throw if there is an error, it behaves as follows: A) if there is no cached data, it will fetch the data (will not wait for the request to finish, nor will it throw or return data) B) if there is cached data, it will essentially do nothing C) if the staletime is met, it will query for the data (the same as A). TLDR; prefetch is useful if you plan on using queries or suspense queries to access your data in components, while ensureQueryData is useful if you plan on using the response within your loader itself (since you need to actually wait on the data). You may also consider using fetch, but since ensureQueryData will immediately return stale data, this can be useful for having more responsive page loads, even if its with stale data

Did you find this page helpful?