Prevent same component from unmounting between routes
I have these three routes:
*
/search/
* /search/$query
* /search/$query/$section
All of these routes render my <SearchIndex /> component with a query and section props if those params are available. In our react-router@v3 setup the component stays mounted between routes if both routes render the same component, but I notice that TanStack Router re-mounts the component each time the matched route changes, which is causing weird state issues and preventing us from doing the transitions we want.
Is it possible for the component to stay mounted in between route changes, if the component each route renders is the same but the props differ?
18 Replies
optimistic-gold•2y ago
How could it stay mounted? those routes have nothing in common
you could lift the search index component up into a
/search route (notice the missing trailing slash, this is NOT the index route at /search/)hilarious-sapphireOP•2y ago
Thanks for the super swift reply @Manuel Schiller!
I'm not sure how it was achieved in
react-router@v3, but it worked there 😅
Interesting idea, if I add it to the /search route, I wouldn't be able to use the TanStack APIs to get the route params right?optimistic-gold•2y ago
hm the problem is that
/search does not know about its children path params
so atleast in TS world they do not exist in that routehilarious-sapphireOP•2y ago
It did work with:
But that's only because I still have the other route files
optimistic-gold•2y ago
so you would need to use the
useParams({strict: false}) way
ah you have that alreadyhilarious-sapphireOP•2y ago
If I use a
$ for _splat , might that work?optimistic-gold•2y ago
(about that
any: don't do that.... the params should be inferred automatically. and when https://github.com/TanStack/router/pull/1664 lands, it will feel a lot nicer)GitHub
fix(react-router): use mapped type instead of intersections for all...
This improves the ts performance significantly ofuseSearch and useParams when strict is false for merging of search and params
Still need to make it default
hilarious-sapphireOP•2y ago
Not ideal as I wouldn't have my two named path params
optimistic-gold•2y ago
ah, you only added those routes because you wanted to express "optional path params"?
hilarious-sapphireOP•2y ago
Yes, my
SearchIndex component has three states:
* /search - The index, showing an empty search bar
* /search/$query - A search for $query was started
* /search/$query/$section - A specific $section for $query was expanded (e.g. "album")optimistic-gold•2y ago
and it must be path params? I would use search params for this
but yeah, that might work
but you would have to split the splat part yourself
optimistic-gold•2y ago
Routing Concepts | TanStack Router React Docs
TanStack Router supports a number of powerful routing concepts that allow you to build complex and dynamic routing systems with ease.
The Root Route
hilarious-sapphireOP•2y ago
I'm afraid that we're already use this URL structure in our production app using react-router and will want to continue supporting this
Agree with you that search params feel more on-point though
optimistic-gold•2y ago
I see your approach (building multiple routes) for optional path params was suggested here as well: https://github.com/TanStack/router/discussions/146#discussioncomment-7984294
GitHub
Optional params? · TanStack router · Discussion #146
In react router v6 they are no longer supported. for example clients/:id? would match both /clients and /clients/1 Is there a way to achieve something like this in react location?
hilarious-sapphireOP•2y ago
As for dropping
<any> on the useParams(), is there any best practice to get the param?
This is what I came up with but it's very verbose:

optimistic-gold•2y ago
this should work:
but as stated above, as soon as this PR lands, this flag will be dropped and the return type will be an optional "intersection" of all path params
inland-turquoise•2y ago
while moving to a shared layout is probably the better move, I'm not sure why a re-mount should occur if you render the same component.
I would get it for:
because that would be a new component, but like this:
should mean the same component is rendered at the same position, which means react should be able to reconcile to the same instance and re-use it ...
optimistic-gold•2y ago
sounds like hoping for an implementation detail?