T
TanStack•3mo ago
ratty-blush

routerWithQueryClient: Invalidating queryClient cache

I'm running into an issue with client-side cache invalidation when using routerWithQueryClient. Problem: I have a loader that prefetches data on the server:
loader: async ({ params, context }) => {
const { slug } = params
const [member, organization] = await Promise.all([
context.queryClient.ensureQueryData(getSelfQueryOptions()),
context.queryClient.ensureQueryData(getSelfOrganizationQueryOptions()),
])
return { member, organization }
}
loader: async ({ params, context }) => {
const { slug } = params
const [member, organization] = await Promise.all([
context.queryClient.ensureQueryData(getSelfQueryOptions()),
context.queryClient.ensureQueryData(getSelfOrganizationQueryOptions()),
])
return { member, organization }
}
The server fetch works, and I assume the cache is hydrated on the client automatically. Later, on the client, after updating member, I try to invalidate the cached query:
const { mutate, isPending } = useMutation({
mutationFn: useServerFn(updateSelfServerFn),
onSuccess: async (memberEntity: Member) => {
const slug = organization.stytch.organization_slug

// Trying to invalidate query
await queryClient.invalidateQueries({
queryKey: queryKeys.getSelf(),
})
},
})
const { mutate, isPending } = useMutation({
mutationFn: useServerFn(updateSelfServerFn),
onSuccess: async (memberEntity: Member) => {
const slug = organization.stytch.organization_slug

// Trying to invalidate query
await queryClient.invalidateQueries({
queryKey: queryKeys.getSelf(),
})
},
})
Core question: Is useQueryClient the correct way to access the query client that routerWithQueryClient provides, or is there a better way to get the same instance that's being used by the router? (when I navigate back to that original page that fetches member/org, its returning stale data instead of refetching first)
17 Replies
raw-harlequin
raw-harlequin•3mo ago
you should be able to get the queryclient via the route context
ratty-blush
ratty-blushOP•3mo ago
is that context separate than what useQueryClient would fetch from? i.e. if I have a deeply nested client component, would I have to either pass the queryClient from route context as props or inject via a react context provider? btw I see how active you are on here answering questions, thank you. Another feather in the cap of the tanstack team
raw-harlequin
raw-harlequin•3mo ago
useQueryClient relies on a react context i was talking about the route context which lives outside of React but i just reviewed our implementation, should have done that first 😄
ratty-blush
ratty-blushOP•3mo ago
so if I had a root route I could inject that into a provider to give react access to it
raw-harlequin
raw-harlequin•3mo ago
that's if you use react-router-with-query
No description
raw-harlequin
raw-harlequin•3mo ago
it's automatically handling this for you
ratty-blush
ratty-blushOP•3mo ago
yeah im using react-router-with-query hrmm
raw-harlequin
raw-harlequin•3mo ago
so useQueryClient will give you the same instance
ratty-blush
ratty-blushOP•3mo ago
interesting, so must be something else going on, thanks for confirming that then, I need to go back to my implementation
raw-harlequin
raw-harlequin•3mo ago
can you explain some more what you are experiencing? what does this mean
(when I navigate back to that original page that fetches member/org, its returning stale data instead of refetching first)
"navigate back " how?
ratty-blush
ratty-blushOP•3mo ago
I have a org/$slug page that fetches member/org via ensureQuery inside a loader. depending on thestate of the member, it will redirect to org/$slug/onboarding, once the member fills out their profile it redirects to org/$slug (since its effectively the landing page for the user), but then it grabs member from the queryCache instead of re-fetching
raw-harlequin
raw-harlequin•3mo ago
how do you consume the data, via useLoaderData?
ratty-blush
ratty-blushOP•3mo ago
in org/$slug/onboarding, I have an explicit invalidate on member/org queryKeys before navigating back to org/$slug. The routing is done onSuccess of some form handler and uses navigate()
ratty-blush
ratty-blushOP•3mo ago
No description
ratty-blush
ratty-blushOP•3mo ago
Yeah this is the RouteComponent, grabs member,org from useLoaderData
raw-harlequin
raw-harlequin•3mo ago
so if you do not use useQuery or useSuspenseQuery, query wont refetch the stale data so you would need to use fetchQuery instead of ensureQueryData in the loader
ratty-blush
ratty-blushOP•3mo ago
Got it, I think I must be misunderstanding what ensureQueryData does. ty, ill give that a try

Did you find this page helpful?