useParams behavior change?
did something change recently to prevent calling
useParams on routes that aren't in the current route?
const { slug} = useParams({ from: "/path/$slug" });
Invariant failed: Could not find an active match from "/path/$slug"
this used to silently just set slug to ""
imagine this useParams that's in a hook so it might be used when the route is something other than /path/blah...34 Replies
exotic-emerald•2y ago
previously this would result in params being
undefined while the types would say it is not. this inconsistency was the reason for this change.
why would you try to access params on routes that don't have params?conventional-tanOP•2y ago
i have a context that wants to pluck out certain state from the current route, IFF it is in the current route, and just not otherwise.
so the context provider wants to "look at the route" and if it finds the match, it goes and fetches the matching object (trpc), and presents it as context.
some routes are /entity/$slug but they have siblings /admin/foo ...
is there a way for me to wrap this context ONLY around the /entity route?
i'm talking regular old react context,... sounds like i should be using tsr context?
exotic-emerald•2y ago
can you explain this in more detail please? which routes exist, on which routes should the context fetching happening etc
conventional-tanOP•2y ago
the issue for me is that i have elements that are not "in the route" that need to behave differently "depending on the route"...
e.g. i have an app shell, with a menu on the left, and a navbar on the top, that has a spotlight search box... with an outlet in the main area.
on the left, one can navigate to /admin/foo which has no params...
or one can select an entity from a list of available entities. and then the links on the left become links to /entity/$slug/a, b, c. etc
but at the same time as that, the top level search box wants to know if we ARE in an entity route, or aren't... since that changes the domain of the search...
so i put this state in a context... and wrapped it around the whole app shell...
where it would lazily provide the state of the entity or not depending on where the route was.
and this has all blown up with the latest version...
what's the plan on not releasing breaking changes with minor versions?
exotic-emerald•2y ago
we did not consider this to be breaking as it was meant to fix an issue where users would rely on the typesafety of the params which then fails at runtime
conventional-tanOP•2y ago
switching from working fine to Invariant failed has to be considered breaking...
exotic-emerald•2y ago
so you want to find out if you are on a specific route? that's the core thing ?
conventional-tanOP•2y ago
as it is now, i've changed the context to call useMatches and go searching through the array looking for the "/entity/$slug" route and extracting (or not) the params there... but that feels pretty gross.
exotic-emerald•2y ago
so why not
useParams with strict false?conventional-tanOP•2y ago
sure, yeah, in english "please get me the params (and search) for this route, if i'm at or below it..."
how does that work?
exotic-emerald•2y ago
useParams hook | TanStack Router Docs
The useParams method returns all of the path parameters that were parsed for the closest match and all of its parent matches.
useParams options
exotic-emerald•2y ago
If false, the opts.from option will be ignored and types will be loosened to Partial<AllParams> to reflect the shared types of all params.
which correctly reflects the possibly undefinedness of the params
vicious-gold•2y ago
@Manuel Schiller i think we lost the good error message here. It used to suggest adding
strict:falseconventional-tanOP•2y ago
hmmm... looking into this...
exotic-emerald•2y ago
true. we should add this error message again
conventional-tanOP•2y ago
if from is ignored when strict = false, and strict defaults to true when from is set, i don't get why we have strict at all... why not just make from optional and if not from then strict = false?
exotic-emerald•2y ago
could be done as well,yes. the current impl makes sure you explicitly set it so you understand the implications
I think the doc is incorrect here btw., you cannot set from if strict is false
conventional-tanOP•2y ago
i don't get the value in strict: false, because the return value is
{} | {} | {
id: string;
} | {
slug: string;
} | {
slug: string;
}
so i can't say const { slug } = useParams({strict: false})exotic-emerald•2y ago
you get all possible combinations
conventional-tanOP•2y ago
i see that
but how is that useful?
somewhere in there i need an
as { slug: string}vicious-gold•2y ago
do: if ('slug' in params)
exotic-emerald•2y ago
try the undocumented
experimental_returnIntersection: truevicious-gold•2y ago
There is no guarantee that it's there, that's the point...
exotic-emerald•2y ago
if you want to avoid the narrowing
vicious-gold•2y ago
I think the narrowing is necessary. useParams().slug.toUppercase() will just fail at runtime. you need to check for existence anyway, and the in operator nicely narrows while doing that
conventional-tanOP•2y ago
i would have preferred to say from: "/entities/$slug"
what if i also had "/foo/$slug"
exotic-emerald•2y ago
the intersection will return a partial so you will have to check for undefined
conventional-tanOP•2y ago
how can i only get the one i want, (other than by never reusing $vars)
exotic-emerald•2y ago
then you should look at
useMatch({strict: false})
same issue with no guarantee which route match is rendered ,so you will have to do some checkingconventional-tanOP•2y ago
ok. thanks for the help!
exotic-emerald•2y ago
something like this
sensitive-blue•2y ago
Running into this same issue - in my Tanstack Query hooks, I want to be able to have typed param values if they exist. I have something like. -
If that hook gets used elsewhere, I believe the router is throwing
Invariant failed: Could not find an active match from "/foo"
If I use this pattern in multiple hooks across the project, I have no way of knowning which hook is causing this problem. Is there a way to determine which call is being problematic?vicious-gold•2y ago
Yeah we should be able to get a stacktrace here
sensitive-blue•2y ago
That would be a huge help! Thank you!