Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: When using unstable_useBlocker with initial value true, Works on the second transition. #10144

Closed
g4yamanaka opened this issue Feb 28, 2023 · 10 comments · Fixed by #10573
Labels

Comments

@g4yamanaka
Copy link

What version of React Router are you using?

6.8.2

Steps to Reproduce

  1. Open https://stackblitz.com/edit/vitejs-vite-lja2ey?file=src/App.tsx
  2. Click "1" link.
  3. Click "home" link.
  4. Click "home" once more.

Expected Behavior

Confirm does pop up when first click.
The "2" link, which is set to true in the middle instead of the default, works as expected.

Actual Behavior

Confirm does pop up when second click.

@g4yamanaka g4yamanaka added the bug label Feb 28, 2023
@jljouannic
Copy link

jljouannic commented Mar 13, 2023

Reproduced in version 6.9.0.

There seems to be some kind of memory leak as the useEffect cleanup call in useBlocker function is never run for the first blocker instance (i.e. when blockerKey === '1').

In fact we always fall in the condition where the "A router only supports one blocker at a time" warning message is displayed.

If you navigate away from a route with a blocker (even if it is inactive) and come back to it, the blockerFunctions size never cease to increase

@jljouannic
Copy link

jljouannic commented Mar 13, 2023

Here is a fork of the official "React Router Navigation Blocking Example" with pnpm-patched dependencies for react-router@3.9.0 and @remix-run/router@1.4.0 packages, only "enhanced" with a few console.log():

https://stackblitz.com/edit/github-v1v4kk?file=package.json

To illustrate the behaviour described above in my previous post:

  • Open the forked "React Router Navigation Blocking Example",
  • When app is loaded, open the console tab of your browser devtools,
  • On the Navigation Blocking Example app on the right, click on the link "Three (Form with blocker)",
  • Then click on "Four",
  • Click again on "Three (Form with blocker)" and so on.

You will see in the devtools console that none of the "even" blockers is ever cleaned up and blockerKey keeps increasing.

@francisco-sanchez-molina

Hello! I'm not exactly sure why it happens, but there's a part that's related to the StrictMode mode, which causes a double load of useEffect, and it's affecting the router context

@jljouannic
Copy link

Double load of useEffect is the expected behaviour with strict mode when in dev mode:

  • React mounts the component.
    • Layout effects are created.
    • Effect effects are created.
  • React simulates unmounting the component.
    • Layout effects are destroyed.
    • Effects are destroyed.
  • React simulates mounting the component with the previous state.
    • Layout effect setup code runs
    • Effect setup code runs

The problem here would be that effect destruction happens after effect has already been called twice

@francisco-sanchez-molina
Copy link

francisco-sanchez-molina commented Mar 13, 2023

Yes! Sorry, I expressed myself poorly. In dev mode and strict mode, the double call is the expected behavior. But it seemed to me that there might be some relationship when looking at the console log of having strict mode active vs not having it:

  • Strict mode off:

image

- Strict mode on:

image

I actually arrived at this issue due to a blocking problem I have in dev but not in prod.

@jljouannic
Copy link

Taken from here:

when running in “strict mode“ React will intentionally double-render components for in order to flush out unsafe side effects.

In our case, isn't the auto-increment of blockerId each time useBlocker is called one of these so-called unsafe side effects?

@jljouannic
Copy link

I have the feeling that the blockerKey state could simply be replaced by a call to the useId hook once the fix to the following issue will be released

@brophdawg11
Copy link
Contributor

This should be addressed by #10573 which will be available in the next release (6.12.2 or 6.13.0)

@brophdawg11 brophdawg11 added the awaiting release This issue have been fixed and will be released soon label Jun 9, 2023
@brophdawg11 brophdawg11 removed their assignment Jun 9, 2023
@github-actions
Copy link
Contributor

🤖 Hello there,

We just published version 6.14.0-pre.0 which involves this issue. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

@github-actions
Copy link
Contributor

🤖 Hello there,

We just published version 6.14.0 which involves this issue. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants