T
TanStack2y ago
flat-fuchsia

Passing context to a component in separate file? / Accessing useRouteContext

Is there any guidance to this? I'd like to have a layout that i can use a separate routes. This has a toolbar but want to render different things in the toolbar depending on the route . I'd like to access some info in context to pass to params on Navigate I tried to call useRouteContext in the layout but got this error / Invariant failed: useMatch("/authenticated/$teamId/properties") is being called in a component that is meant to render the '/authenticated/$teamId/properties/map' route. Did you mean to 'useMatch("/authenticated/$teamId/properties", { strict: false })' or 'useRoute("/authenticated/$teamId/properties")' instead? Due to react-refresh issues I moved the layout to a separate module, but wondering how to type this in the layout.
const propertiesRoute = new Route({
getParentRoute: () => teamIdRoute,
path: 'properties',
component: ({ useRouteContext }) => <DataEntityLayout />,
})
const propertiesRoute = new Route({
getParentRoute: () => teamIdRoute,
path: 'properties',
component: ({ useRouteContext }) => <DataEntityLayout />,
})
12 Replies
deep-jade
deep-jade2y ago
use the strict:false option This will loosen up the warning And let you access the nearest route context. It also loosens up the type safety too, but there’s not much you can do for shared route types
other-emerald
other-emerald2y ago
Using v1.4.3, I can access the property from the nearest context, but there's a type error despite the fact that the union appears to include an object with the property. Am I accessing it as expected in this example? https://stackblitz.com/edit/tanstack-router-mbme8z?file=src%2Froutes%2F_test%2Fexample.tsx
Cory Deppen
StackBlitz
Router Kitchen Sink React Query File Based Example (forked) - Stack...
Run official live example code for Router Kitchen Sink React Query File Based, created by Tanstack on StackBlitz
other-emerald
other-emerald2y ago
I modified the example to use v1.4.6 and include trying to access the context using the useRouteContext method on RouteApi, but that produces a type error because strict is not an option for that method. Both ways prevent the invariant error, though.
other-emerald
other-emerald2y ago
I've added a third component to my example to show the error (same as the OP) when silencing the type error using as const with the from option mentioned in a comment on issue 901. I don't mind adding a new issue if you feel this may be a bug. https://github.com/TanStack/router/issues/901
GitHub
useRouteContext typing does not include context from beforeLoad ·...
Describe the bug // router.tsx const dashboard = new Route({ getParentRoute: () => root, path: 'dashboard', beforeLoad: () => { return { session: 'abc123' } }, component: Dash...
exotic-emerald
exotic-emerald2y ago
what do you think is a bug here? that you need to use as const?
other-emerald
other-emerald2y ago
I'm really unsure if it's a bug or if I'm using it incorrectly, but I can't seem to get around the fact that there's either a type error of some sort or the invariant error. The invariant error isn't thrown when strict: false is used, but that seemingly can't be used with the from option. If I use strict: false, the context property is no longer typed but the invariant error is no longer thrown.
exotic-emerald
exotic-emerald2y ago
the context is typed with strict: false however, now you get the union of all route contexts
exotic-emerald
exotic-emerald2y ago
No description
exotic-emerald
exotic-emerald2y ago
I see that _test layout route adds label to the route context. So all child routes have access to it since they inherit the parent route's context. What prevents you from
const { label } = useRouteContext({ from: '/_test/third' as const });
const { label } = useRouteContext({ from: '/_test/third' as const });
?
other-emerald
other-emerald2y ago
I was trying to avoid having to specify the from since it's used in a hook to prevent duplicating several lines that use a query ref that's in context and read data from the cache. Having to specify the from that needs to be in sync with the current route also seems like it might introduce a bug in the app if the route moves but the use of useRouteContext in the related component doesn't get updated. That's partially why I thought Tanner recommended strict: false above.
exotic-emerald
exotic-emerald2y ago
then you need to add a runtime check to the return value of {strict: false}:
if ('label' in x) {
...
}
if ('label' in x) {
...
}
other-emerald
other-emerald2y ago
That may be tricky in my case, since the hook to read the cache can't be used inside a conditional. If I wanted to declare a variable outside the conditional and capture the query ref from context inside the conditional, it seems like I'd need to know the type of the context property. I was trying to avoid that, though, since it seems like it should be able to be inferred from the context.

Did you find this page helpful?