-
Notifications
You must be signed in to change notification settings - Fork 70
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
Focus trap doesn't work in React 18 #720
Comments
That is strange. What you have there is all it should take. I appreciate the repro. I can't repro this locally -- but I did notice that you're running this code in strict mode, and when not in strict mode, it works as expected. So, what is happening in strict mode that's preventing the trap from working. Likely some violation is happening somewhere that's silently blowing up or preventing the trap from finding something, and causing it to render, but not activate. 🤔 |
Tracing this out, seems nothing is blowing up in strict mode. The trap gets created, everything looks good. And yet it silently just doesn't work. |
I see. It's because in strict mode, React unmounts and remounts the React doesn't re-render on re-mount the second time, though, and doesn't re-execute the callback ref, so I will assume here that React is remounting onto the same DOM state as well, which means the trap, on remount, if exists, should check if it should be active and isn't and just reactivate and assume what it thinks the container elements are still exist in the DOM. If React doesn't re-execute the callback refs, that won't trigger getting new DOM nodes for the container elements (when you don't specify the |
For the record, I am not a fan of this strict mode. For one thing, it violates correct assumptions about componentWillUnmount
(emphasis mine) Strict mode violates this assumption. I get that React is looking forward to this day where they will decide which parts of the tree to unmount when the user goes away somewhere, but strict mode violates normal assumptions, and then they expect the entire community to not operate under those assumptions?? |
In React strict mode, the trap gets immediately unmounted and remounted after first mount. The trap deactivates automatically on unmount, so on remount, we try to restore the trap to its previous active/paused state based on the component's existing state. React does not re-render the component, nor does it call callback refs again, so we have no choice but to assume the DOM hasn't changed and the existing trap's container elements are still in the DOM... Way to go React for strict mode violating the assumption of `componentWillUnmount()`, "Once a component is unmounted, it will never be mounted again." :(
Fixes #720 In React strict mode, the trap gets immediately unmounted and remounted after first mount. The trap deactivates automatically on unmount, so on remount, we try to restore the trap to its previous active/paused state based on the component's existing state. React does not re-render the component, nor does it call callback refs again, so we have no choice but to assume the DOM hasn't changed and the existing trap's container elements are still in the DOM... Way to go React for strict mode violating the assumption of `componentWillUnmount()`, "Once a component is unmounted, it will never be mounted again." Not a fan.
Fixes #720 In React strict mode, the trap gets immediately unmounted and remounted after first mount. The trap deactivates automatically on unmount, so on remount, we try to restore the trap to its previous active/paused state based on the component's existing state. React does not re-render the component, nor does it call callback refs again, so we have no choice but to assume the DOM hasn't changed and the existing trap's container elements are still in the DOM... Way to go React for strict mode violating the assumption of `componentWillUnmount()`, "Once a component is unmounted, it will never be mounted again." Not a fan. Also bumped react-dom to 18.2.0 since react was already there, and set NODE_ENV for different builds.
Fixes #720 In React strict mode, the trap gets immediately unmounted and remounted after first mount. The trap deactivates automatically on unmount, so on remount, we try to restore the trap to its previous active/paused state based on the component's existing state. React does not re-render the component, nor does it call callback refs again, so we have no choice but to assume the DOM hasn't changed and the existing trap's container elements are still in the DOM... Way to go React for strict mode violating the assumption of `componentWillUnmount()`, "Once a component is unmounted, it will never be mounted again." Not a fan. Also bumped react-dom to 18.2.0 since react was already there, and set NODE_ENV for different builds.
@all-contributors add @moroshko for bug ...Although I wouldn't technically consider this a bug, but nonetheless, whatever I may think, many people seem to run in strict mode, so I definitely appreciate the heads-up here. Thank you, @moroshko ! |
I've put up a pull request to add @moroshko! 🎉 |
Will be published in 9.0.2 |
Thank you @stefcameron for such a quick fix! |
My pleasure! |
I'm using
focus-trap-react 9.0.1
and the focus trap doesn't seem to work.If I focus on the first
<input>
and pressTab
twice, I land on the second<input>
that sits outside the trap.What am I missing?
Codesandbox
The text was updated successfully, but these errors were encountered: