Using navigate in useEffect leads to false routing
1. I navigate via a
<Link>
to the /about
page.
2. The component of the /about
page has a useEffect
which executes navigate
function.
3. The navigate
only applies an id
query param, not more.
4. Expect: I would expect the final path to be /about?id=1234
5. Actual: The router navigates back to the home route /
I'm coming from and applies the id=1234
query param there instead.
I created a repo with a reproduction and some additional notes in the README.
Reproduction: https://github.com/lukaskoeller/tanstack-react-router-useEffect-navigate-reproduction
I'm not sure if it's something I do wrong or rather a library bug, that's why I'm asking here first. Anybody that can help?9 Replies
eastern-cyanOP•14mo ago
E.g. when I set a timeout, it is working as expected. So I would assume the useEffect just runs too early when the navigation in the lib is not yet done?
exotic-emerald•14mo ago
this most likely is a bug in router
exotic-emerald•14mo ago
hopefully it was fixed now in https://github.com/TanStack/router/releases/tag/v1.45.5
GitHub
Release v1.45.5 · TanStack/router
Version 1.45.5 - 7/18/24, 6:52 PM
Changes
Fix
react-router: use current matches for fromMatches and only build new matches when location overridden (#1968) (99f7352) by Christopher Horobin
Test
...
exotic-emerald•14mo ago
can you please try it out ?
eastern-cyanOP•14mo ago
Yes this fixed it! Brillian. Thanks a lo @Manuel Schiller
Heads up. A very similar problem happened in our production app again. This time, the router wouldn't navigate back to the "old" page but just wouldn't add the search params.
See the affected code using v1.45.8 here:
data
here related to a useQuery
. After removing the loader
from the page it worked for the inital load. That means when the useEffect
was executed after querying necessary data. It wouldn't work with cached data
after returning to the dashboard. The current dirty workaround is a setTimeout
.
I'm currently trying to reproduce the issue in this repo: https://github.com/lukaskoeller/tanstack-react-router-useEffect-navigate-reproduction. Yet I couldn't reproduce it but will let you know once I could
Overall the behavior in our app is really weird. Now I experienced search params for /benchmark
are applied for other pages like /calculator
. Also removing certain components and adding them suddently made the navigation as in the code above work.frozen-sapphire•14mo ago
Shouldn't you be cleaning up the setTimeout here? If not, across renders an outdated setTimeout could fire that'd cause old navigations to be fired.
eastern-cyanOP•14mo ago
yeah you're right. That should be fixed. Nonetheless, the last hours I'm trying to see what is causing the buggy behavior with search params in our app, I removed the
setTimeout
@Manuel Schiller @Sean Cassiere
Ok, at least one thing I was able to reproduce now. See reproducer. https://github.com/lukaskoeller/tanstack-react-router-useEffect-navigate-reproduction
The issue appears when two useEffect
are executed shortly after each other. The time the second useEffect
executes the navigate
(see example below), the old
params are still empty ({}
) although the navigate
of the useEffect
was executed first and applied firstId
. Thus, expected would be that the old
of the navigate
running shortly after is not empty ({}
) but holds the firstId
({ firstId: 1337 }
).
Now that I'm thinking about it, it is probably because the Promise of the first navigate
hasn't resolved at the time the second navigate
fires 🤔exotic-emerald•14mo ago
yes, most likely. why do you have two useEffect that both navigate independently from each other ?
eastern-cyanOP•14mo ago
The other
useEffect
lives in another component and is executed as soon as certain params are available which triggers isLoading
of another useQuery
There's another issue with default search params. See reproducer: https://github.com/lukaskoeller/tanstack-react-router-useEffect-navigate-reproduction?tab=readme-ov-file#reproduction-2
Given the following validateSearch
:
when you navigate the page, useSearch
returns the default values, but they are not attached to the URL. That only happens when you reload the page. I would expect search params in the URL anytime when params are returned via useSearch
Turns out there's already an open github issue for that: https://github.com/TanStack/router/issues/1184
Created a github issue for this one: https://github.com/TanStack/router/issues/2028