You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Component doesn't unmount before router location/state changes while navigating, can cause infinite rendering聽#3340
馃グIf you don't want to read all these detailed info with my real use cases, please refer to below comments for a real minimum reproduction, as it self-explained the issue.
馃グAlso please refer to this comment for what I've found and my thoughts about the issue.
I have a <ProtectedRoute /> component, which will redirect the application to / (landing page) if no such __INTERNAL_NAVIGATION__ flag is provided in the route state.
It's only wrapped in certain routes, and definitely the landing page is not wrapped with it.
However, once it detected the illegal visit to certain protected route, it should navigate back to / route immediately, but now it's somehow falling into infinity rerender until maximum update depth exceeded, behaves like the roote path / is wrapped by the <ProtectedRoute /> component as well, but it's definitely not.
NOTE: Please take a look at the below comment if you want a straightforward & small reproduction which I find out later after posting this.
Steps to Reproduce the Bug or Issue
PATH A:
Open console (I have pathname printed to the console for debugging)
Click About link (It successfully redirect back to Home route, which is not wrapped by <ProtectedRoute /> but it's still rendering, causing infinite rerender)
See the console
PATH B:
it's even worse. All navigation is valid, but it still breaks.
Open console
Click This-should-work link (This is a valid navigation because I passed the flag __INTERNAL_NAVIGATION__ to that protected route /this-should-work
Click Home link (This is where things go wrong. Home route is not wrapped by <ProtectedRoute /> at all but it is still rendering it and cause infinite rerender)
See the console
Expected behavior
It should redirect to / by only printing the error warning once (twice in StrictMode), with pathname /about.
But in reality, it falls into infinity rerendering, with pathname /about for once, but the rest are all /.
This shouldn't happen because / route is not wrapped by <ProtectedRoute /> component at all.
Screenshots or Videos
Platform
OS: Windows
Browser: Chrome
Version: 132.0.6834.160
Additional context
Currently migrating from react-router-dom to @tanstack/react-router. It worked fine in react-router-dom.
The ultimate conclusion is, after successfully navigating back to / (which is the Home page), <ProtectedRoute /> should be out of the component tree because it's not part of what's being defined in the component property of / route.
changed the title [-]Wrong component rendered / Infinite rerender while navigating (馃檹Please see the content and help me with the title馃檹)[/-][+]Wrong component rendered with the precense of `useLocation()`[/+]on Feb 6, 2025
changed the title [-]Wrong component rendered with the precense of `useLocation()`[/-][+]Wrong component rendered with the precense of `useLocation()`, can cause infinite rerender[/+]on Feb 6, 2025
changed the title [-]Wrong component rendered with the precense of `useLocation()`, can cause infinite rerender[/-][+]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender[/+]on Feb 6, 2025
I'm playing around the things in my real app, and found out that the route state is actually being modified first when a navigate() happens, then of course useLocation().state will be changed.
But at that moment, the previous component is NOT unmounted yet.
In my route /b, I'm checking whether something exists in the route state, if not I'm going to show an error screen.
When I'm navigating to /a, route state has already been changed after calling navigate(), but the component of /b is NOT unmounted, so the error screen will show up until it actually unmounts.
This is... from my perspective, it is FUNDAMENTALLY wrong.
The ideal order should be
navigate() called / <Link /> clicked, etc. whatever, navigation happened
Unmount the previous route's component
Update route state/location, etc.
.... More router internal stuff that I don't know ....
Mount the new route's component
But currently, 2 is happening after 3, or even after 4.
Sorry that I don't have much knowledge about how the router works exactly under the hood, but what I described above may also be the cause of all those issues.
changed the title [-]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender[/-][+]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender / Component didn't unmount before router location/state changes[/+]on Feb 6, 2025
changed the title [-]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender / Component didn't unmount before router location/state changes[/-][+]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender / Component doesn't unmount before router location/state changes[/+]on Feb 6, 2025
changed the title [-]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender / Component doesn't unmount before router location/state changes[/-][+]Component doesn't unmount before router location/state changes while navigating, can cause infinite rendering[/+]on Feb 6, 2025
changed the title [-]Component doesn't unmount before router location/state changes while navigating, can cause infinite rendering[/-][+]鈿狅笍鈥硷笍Component doesn't unmount before router location/state changes while navigating, can cause infinite rendering[/+]on Feb 7, 2025
changed the title [-]鈿狅笍鈥硷笍Component doesn't unmount before router location/state changes while navigating, can cause infinite rendering[/-][+]Component doesn't unmount before router location/state changes while navigating, can cause infinite rendering[/+]on Feb 8, 2025
Close in favour of #3110, hopefully someone can have a look and give an official comment on it whether this is the desired behaviour or what's recommended to do.
Activity
xsjcTony commentedon Feb 6, 2025
The ultimate conclusion is, after successfully navigating back to
/(which is theHomepage),<ProtectedRoute />should be out of the component tree because it's not part of what's being defined in thecomponentproperty of/route.But it's still rendering.
[-]Wrong component rendered / Infinite rerender while navigating (馃檹Please see the content and help me with the title馃檹)[/-][+]Wrong component rendered with the precense of `useLocation()`[/+][-]Wrong component rendered with the precense of `useLocation()`[/-][+]Wrong component rendered with the precense of `useLocation()`, can cause infinite rerender[/+]xsjcTony commentedon Feb 6, 2025
This is the smallest reproduction I can make: https://stackblitz.com/edit/github-mqst1ckv?file=src%2Fcomponents%2FWeirdo.tsx
Turns out the problem with the
useLocation()called in theroute'scomponentproperty's component tree.Read the comment in the
Weirdo.tsxand monitor the console while navigating back and forth, you'll know what's happening.[-]Wrong component rendered with the precense of `useLocation()`, can cause infinite rerender[/-][+]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender[/+]xsjcTony commentedon Feb 6, 2025
This is just so weird...
I'm playing around the things in my real app, and found out that the
route stateis actually being modified first when anavigate()happens, then of courseuseLocation().statewill be changed.But at that moment, the previous component is NOT unmounted yet.
In my route
/b, I'm checking whether something exists in theroute state, if not I'm going to show an error screen.When I'm navigating to
/a,route statehas already been changed after callingnavigate(), but the component of/bis NOT unmounted, so the error screen will show up until it actually unmounts.This is... from my perspective, it is FUNDAMENTALLY wrong.
The ideal order should be
navigate()called /<Link />clicked, etc. whatever, navigation happenedBut currently, 2 is happening after 3, or even after 4.
Sorry that I don't have much knowledge about how the router works exactly under the hood, but what I described above may also be the cause of all those issues.
Please have a look and let me know, thanks.馃挌馃檹
[-]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender[/-][+]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender / Component didn't unmount before router location/state changes[/+][-]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender / Component didn't unmount before router location/state changes[/-][+]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender / Component doesn't unmount before router location/state changes[/+][-]Wrong component rendered with the presence of `useLocation()`, can cause infinite rerender / Component doesn't unmount before router location/state changes[/-][+]Component doesn't unmount before router location/state changes while navigating, can cause infinite rendering[/+][-]Component doesn't unmount before router location/state changes while navigating, can cause infinite rendering[/-][+]鈿狅笍鈥硷笍Component doesn't unmount before router location/state changes while navigating, can cause infinite rendering[/+][-]鈿狅笍鈥硷笍Component doesn't unmount before router location/state changes while navigating, can cause infinite rendering[/-][+]Component doesn't unmount before router location/state changes while navigating, can cause infinite rendering[/+]xsjcTony commentedon Feb 8, 2025
Close in favour of #3110, hopefully someone can have a look and give an official comment on it whether this is the desired behaviour or what's recommended to do.