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
When navigating from a source route (i.e. /route-a) to a destination route (/route-b) after a promise, the component for the source route is re-rendered after the navigation - when the URL is already set to the destination.
This is unexpected, since PageA should only render on /route-a, not /route-b
If you repro with the following steps, the extra render does not occur:
Go to /route-a
Open the console
Click navigate immediately
The console will only read:
PageA render, pathname: /route-a
Which is what I would expect in both cases.
Why this is an issue
Say I have a condition in PageA to check for a search param (i.e. auth=1), and if it does not exist, navigate to an earlier route where the search param is populated. When navigating from /route-a to /route-b, I don't include the search param i.e. I would navigate from /route-a?auth=1 to /route-b , not /route-b?auth=1. When navigating after promise, PageA is re-rendered with the URL of /route-b. Since the auth=1 search param is not present, my condition kicks in, and I'm navigated away from the destination route. This is more or less the scenario that led me to root-cause this issue.
I'm seeing a very similar issue, but in a slightly different constellation - maybe they are related, I'm not sure. Mine happens when you use the browser's back/forward navigation buttons.
You can see this in the following sandbox: https://3xskvp.csb.app/page/1 - please note that, because it seems to be related to the browser's native functionality, you need to observe this in the "deployed" version of the sandbox, not in sandbox.io's preview browser. For study purposes, here's the editable version of the sandbox: https://codesandbox.io/p/sandbox/stupefied-frost-3xskvp
I have two routes, in the example /page/:id and /a-different-page/:id. The associated components print the current useLocation() and useParams() values to the console.
When you switch via the routing links, everything is fine. But if you navigate to a page and then use the browser's back button, the route being left re-renders unexpectedly, having received the new location (like @ElanMedoff describes), but also the old params map from the previous route.
This is unfortunate because in my real world case, I have side-effects in a useEffect hook which shouldn't fire when the component is actually being unmounted. And even if they do, they receive params which don't match what the route/component expects.
No promises involved in my case, so the setup is quite different, but the effect looks similar enough that maybe the problems are related and this could help for analysis.
Edit: FWIW, my case does use createRoot, and the issue still happens (to add to the confusion).
This sounds like a tearing (reactwg/react-18#69) issue, but I just can't figure out why it happens. Wouter relies on useSyncExternalStore and this hook should be tearing-safe. I'm out of ideas for now, but I will keep digging.
Issue
When navigating from a source route (i.e.
/route-a
) to a destination route (/route-b
) after a promise, the component for the source route is re-rendered after the navigation - when the URL is already set to the destination.Reproducing
I was able to reproduce this issue in a code sandbox: https://codesandbox.io/p/sandbox/exciting-wilson-l9sk9x
/route-a
navigate after promise
The console will read:
This is unexpected, since
PageA
should only render on/route-a
, not/route-b
If you repro with the following steps, the extra render does not occur:
/route-a
navigate immediately
The console will only read:
Which is what I would expect in both cases.
Why this is an issue
Say I have a condition in
PageA
to check for a search param (i.e.auth=1
), and if it does not exist, navigate to an earlier route where the search param is populated. When navigating from/route-a
to/route-b
, I don't include the search param i.e. I would navigate from/route-a?auth=1
to/route-b
, not/route-b?auth=1
. When navigating after promise,PageA
is re-rendered with the URL of/route-b
. Since theauth=1
search param is not present, my condition kicks in, and I'm navigated away from the destination route. This is more or less the scenario that led me to root-cause this issue.Notes
3.4.0
createRoot
, the extra render does not occur, see https://codesandbox.io/p/sandbox/musing-dust-qm6mlxThe text was updated successfully, but these errors were encountered: