How to wait for auth check in beforeLoad hooks after router.invalidate? #7646
-
|
We use The problem I keep running into is when the user auth changes from authorized to not authorized, I can't figure out how to invalidate the router and the queries in such a way that the query in the route component isn't run before the For example, for this component I don't want to fetch the residency data if the user does not have access to the residency feature because that will cause an error. export const Route = createFileRoute('/_appLayout/residency')({
beforeLoad: async ({ context, location }) => {
// check if user has feature
const hasFeature = await queryClient.fetchQuery(hasResidencyFeatureQueryOptions);
// redirect if user does not have feature
if (!hasFeature) {
throw redirect({
to: '/feature-unavailable',
search: {
featureType: 'Residency_Module',
redirect_url: getRedirectUrl(location),
},
});
}
},
loader: ({ context }) => {
// This will throw an error if called when user does not have access to residency feature
void context.queryClient.prefetchQuery(residencyDataQueryOptions);
},
component: () => {
// This will throw an error if called when user does not have access to residency feature
const {data} = useQuery(residencyDataQueryOptions);
return <ResidencyDataView data={data} />
},
});When user auth changes from residency feature enabled -> disabled, we run I thought this would work: await queryClient.invalidateQueries({ refetchType: 'none' });
await router.invalidate();But the route component is rendered before the This happens specifically when the user transitions from authorized -> not authorized, I assume because the route component stays mounted during the transition. If you navigate to the page directly, the component is not mounted at all, as expected. Is there any way to invalidate the router in such a way that it will unmount the component and then not remount until after the |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
yeah this is the missing piece: plain what you want is to push the matches back into await router.invalidate({ forcePending: true })
so the order that worked for me: await queryClient.invalidateQueries({ refetchType: 'none' })
await router.invalidate({ forcePending: true })the |
Beta Was this translation helpful? Give feedback.
yeah this is the missing piece: plain
router.invalidate()marks the matchesinvalid: truebut it leaves their status assuccess, so the current match stays resolved and keeps rendering its component (and youruseQueryfires) whileload()re-runs beforeLoad in the background. that's the brief flash you're seeing.what you want is to push the matches back into
pendingso the component unmounts until beforeLoad finishes:forcePendingresets matched routes tostatus: 'pending'and clears their error, so on the re-run the route shows its pendingComponent instead of the stale component, and your redirect in beforeLoad gets to run before anything r…