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
causal-orange•16mo 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/
)metropolitan-bronzeOP•16mo 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?causal-orange•16mo 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 routemetropolitan-bronzeOP•16mo ago
It did work with:
But that's only because I still have the other route files
causal-orange•16mo ago
so you would need to use the
useParams({strict: false})
way
ah you have that alreadymetropolitan-bronzeOP•16mo ago
If I use a
$
for _splat
, might that work?causal-orange•16mo 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
metropolitan-bronzeOP•16mo ago
Not ideal as I wouldn't have my two named path params
causal-orange•16mo ago
ah, you only added those routes because you wanted to express "optional path params"?
metropolitan-bronzeOP•16mo 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")causal-orange•16mo 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
causal-orange•16mo 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
metropolitan-bronzeOP•16mo 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
causal-orange•16mo 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?
metropolitan-bronzeOP•16mo 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:

causal-orange•16mo 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
correct-apricot•16mo 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 ...
causal-orange•16mo ago
sounds like hoping for an implementation detail?