remix-run / react-router

Declarative routing for React

Home Page:https://reactrouter.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bug]: `<Navigate>` can be canceled by `navigate("?x")` even if guarded by `if(navigation.state === "idle")`

jtbandes opened this issue · comments

What version of React Router are you using?

6.15.0

Steps to Reproduce

Call if (navigation.state === "idle") { navigate("?searchparams"); } in a useEffect while a <Navigate to="/foo" /> is being executed.

See demo: https://stackblitz.com/edit/github-ymgiss?file=src%2Fapp.tsx

Expected Behavior

If navigation.state === "idle", then navigate() should not interfere with <Navigate />.

Actual Behavior

navigation.state === "idle" but a <Navigate /> is actually in progress. The in-progress navigation is canceled, leaving the page in an incorrect state where the route that used <Navigate /> is visible.

image

(The text "navigating..." should never be visible because it's in a component that uses <Navigate />)

Note: if navigate("/bar") is used instead of navigate("?abc"), the problem does not occur.

At the time of rendering, the navigation state is indeed in an idle state. There is no loader on the routes, so the state goes to idle immediately. If you add a dummy loader, you'll see it get into an infinite rendering loop, as this effect doesn't have an end state (it will navigate once every loading completes).