T
TanStack17mo ago
flat-fuchsia

Sharing Query between Routes

How should I be sharing Tanstack Query data between children routes? I'm a bit confused on when to use context provider vs accessing context or just using Tanstack Query directly in component. For example, I have a route /_cash-flow with sub routes (tabs) /_cash-flow/typeA, /_cash-flow/type2A, etc. I use a loader in /_cash-flow to import 'cash-flow' table data for user and /typeA is a filter on that data, so each 'type' page provides a CRUD interface for just that table data filtered on 'typeA' like /typeA/add or /typeA/$id I created a /$type route that gets the type for filtering the cash flow table data, but not sure how to handle it. I have tried using a loader within _cash-flow then within the /$type route component, I use Tanstack Query to fetch the data and filter, but the transition between these pages/tabs is considerably slow for a little amount of data. The _cash_flow route doesn't directly use the cash flow data, but each of the siblings use the same data so figured it would be a good place to load it once. I have some other similar situations where I have a parent route and several different sibling routes use the same data. I can't quite follow the docs to figure out if in a fileroute's loader how to fetch data and make it available for children
3 Replies
rising-crimson
rising-crimson17mo ago
If you are TanStack Query, then you can just read the data directly from the QueryClient's cache. I'd go for a setup like this.
// src/routes/posts.$postId.tsx
const PostsRoute = createFileRoute('/posts/$postId')({
beforeLoad: ({ params }) => {
return {
sharedPostByIdOptionsForSomething: queryOptions({
queryKey: ['post', params.postId, 'something']
})
}
},
loader: ({ context }) => context.queryClient.ensureQueryData(context.sharedPostByIdOptionsForSomething)
})

// src/routes/posts.$postId.tab1.tsx
const PostsTab1Route = createFileRoute('/posts/$postId/tab1')({
component: PostsTab1RouteComponent
})

function PostsTab1RouteComponent() {
const { sharedPostByIdOptionsForSomething } = PostsTab1Route.useRouteContext()
const { data } = useSuspenseQuery(sharedPostByIdOptionsForSomething)
// ...
}
// src/routes/posts.$postId.tsx
const PostsRoute = createFileRoute('/posts/$postId')({
beforeLoad: ({ params }) => {
return {
sharedPostByIdOptionsForSomething: queryOptions({
queryKey: ['post', params.postId, 'something']
})
}
},
loader: ({ context }) => context.queryClient.ensureQueryData(context.sharedPostByIdOptionsForSomething)
})

// src/routes/posts.$postId.tab1.tsx
const PostsTab1Route = createFileRoute('/posts/$postId/tab1')({
component: PostsTab1RouteComponent
})

function PostsTab1RouteComponent() {
const { sharedPostByIdOptionsForSomething } = PostsTab1Route.useRouteContext()
const { data } = useSuspenseQuery(sharedPostByIdOptionsForSomething)
// ...
}
flat-fuchsia
flat-fuchsiaOP17mo ago
Thanks, that does seem like a clean approach. I did some digging and found out the slow loading was due to 'const { location } = useRouterState()' in the child route and using location for relative route nav. If I want to link to nested route, is there a better way to do this without throwing type errors?
<Link
to={`./$id`}
params={{ id: cashFlowData.id }}
>
<Link
to={`./$id`}
params={{ id: cashFlowData.id }}
>
plain-purple
plain-purple17mo ago
you need to specify from

Did you find this page helpful?