-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Description
Reproduction
When you have some code that needs to perform two navigation operations programmatically, you can have something like this
const navigate = useNavigate();
...
await navigate("foo");
await navigate("foo?bar", {replace: true});Which works fine, but if you add a blocker to the mix and have e.g.
const navigate = useNavigate();
const blocker = useBlocker(true);
useEffect(() => {
setTimeout(() => {
if (blocker.state === 'blocked') {
blocker.proceed();
}
}, 500);
}, [blocker.state]);
...
await navigate("foo");
await navigate("foo?bar", {replace: true});Then it no longer works correctly because the first await navigate("foo"); will not actually wait for navigation, it will only wait for the blocker to be blocked. The second navigate call will then invoke before the blocker has been able to proceed, and seemingly overwrite the first call. As a result, the history is incorrect.
Is there a reason that navigate does not await the blocker to proceed and only at that point resolve? Then this should work also when using a blocker
Example in https://stackblitz.com/edit/github-llreimye?file=app%2Froutes%2Fhome.tsx
System Info
System:
OS: Linux 5.0 undefined
CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 0 Bytes / 0 Bytes
Shell: 1.0 - /bin/jsh
Binaries:
Node: 20.19.1 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 10.8.2 - /usr/local/bin/npm
pnpm: 8.15.6 - /usr/local/bin/pnpm
npmPackages:
@react-router/dev: ^7.7.1 => 7.8.0
@react-router/node: ^7.7.1 => 7.8.0
@react-router/serve: ^7.7.1 => 7.8.0
react-router: ^7.7.1 => 7.8.0
vite: ^6.3.3 => 6.3.5Used Package Manager
npm
Expected Behavior
useNavigate() should behave like it is documented:
The implementation in Data/Framework mode also returns a Promise that resolves when the navigation is completed.
Actual Behavior
The returned promise resolves before the navigation is completed