T
TanStack3w ago
inland-turquoise

Understanding Route loader query vs component hook query

Can anyone help me to understand the difference between executing a query in the loader vs in the component? I have these two examples
//$id.edit.tsx
// ensureQuery in the Route loader
export const Route = createFileRoute('/_app/orders/$id/edit')({
loader: ({params, context: { queryClient } }) => {
return queryClient.ensureQueryData(getOrderQuery(params.id));
},
component: EditOrder,
})
function EditOrder() {
const order = useLoaderData({from: Route.id});
console.log('EditOrder: data', order);
return( ... )
}
//$id.edit.tsx
// ensureQuery in the Route loader
export const Route = createFileRoute('/_app/orders/$id/edit')({
loader: ({params, context: { queryClient } }) => {
return queryClient.ensureQueryData(getOrderQuery(params.id));
},
component: EditOrder,
})
function EditOrder() {
const order = useLoaderData({from: Route.id});
console.log('EditOrder: data', order);
return( ... )
}
and this
// No route loader. useQuery hook in the component
export const Route = createFileRoute('/_app/orders/$id/edit')({
component: EditOrder,
})
function EditOrder() {
const {id} = useParams({from: Route.id});
const {data:order} = useQuery(getOrderQuery(id))
console.log('EditOrder: data', order);
return( ... )
}
// No route loader. useQuery hook in the component
export const Route = createFileRoute('/_app/orders/$id/edit')({
component: EditOrder,
})
function EditOrder() {
const {id} = useParams({from: Route.id});
const {data:order} = useQuery(getOrderQuery(id))
console.log('EditOrder: data', order);
return( ... )
}
From what I see, with the first one, the whole page waits to render while the data loads (maybe the router pending component shows) and there is no background fetching when you navigate back, or re-focus on the page (but there is caching). With the second, the page starts to render immediately and you have to check for loading state in the jsx. Background fetches happen on navigation and re-focus. Is it just a matter of what I want the loading and background fetching behavior to be?
6 Replies
rival-black
rival-black3w ago
your understanding is correct, a couple things worth mentioning 1. fetching on "re-focus" is configurable in the second case if you don't want that 2. I'm 99% sure you can support fetching on re-focus in the first case but it requires more code 3. the first case supports "preloading" which can be a desireable UX improvement – docs link
Preloading | TanStack Router React Docs
Preloading in TanStack Router is a way to load a route before the user actually navigates to it. This is useful for routes that are likely to be visited by the user next. For example, if you have a li...
inland-turquoise
inland-turquoiseOP3w ago
Thanks!
rival-black
rival-black3w ago
You can also combine them, you'd prefetch the data in the loader (the loader runs before the component downloads) then you'd subscribe to updates through the hook This prevents cascading requests, instead of having
Route Download > Data fetching
Route Download > Data fetching
you'd have them run in parallel
fair-rose
fair-rose3w ago
@pit you also had this question. The explaination might help
inland-turquoise
inland-turquoiseOP3w ago
"Prefetch the data in the loader", does that mean using queryClient.prefetchQuery() vs queryClient.ensureQueryData() ?
rival-black
rival-black3w ago
Yes. About which method to use, read the docs and use whichever suits your needs.

Did you find this page helpful?