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
Fix: make v5 Router compatible with v18 StrictMode #8831
Conversation
Just tested these changes on a large app at the moment and it looks to be working great. 👏
|
@timdorr 👋 friendly ping. Any thoughts on the approach I took here? |
I think this looks good. I'll merge it in and see if we can get this pushed in the next few days. |
@timdorr any way we could get this in today? |
I'm dealing with a burst water line in my house, so I've been derailed a bit. I'm still planning on releasing this, though! Sorry for the delay in my end. |
@timdorr no worries! Good luck with your burst water line, hope it gets fixed fast! |
OK, got it published now! |
@timdorr looks like something went wrong when publishing this. our work around was to add a resolution to force react-router >= 3.0.0 but it is likely that this version may cause issues this is the problematic bit:
|
Just fixed that in 5.3.3 😵 |
Thanks |
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [react-router](https://togithub.com/remix-run/react-router) | [`5.2.0` -> `5.3.4`](https://renovatebot.com/diffs/npm/react-router/5.2.0/5.3.4) | [![age](https://badges.renovateapi.com/packages/npm/react-router/5.3.4/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/react-router/5.3.4/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/react-router/5.3.4/compatibility-slim/5.2.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/react-router/5.3.4/confidence-slim/5.2.0)](https://docs.renovatebot.com/merge-confidence/) | | [react-router-dom](https://togithub.com/remix-run/react-router) | [`5.2.0` -> `5.3.4`](https://renovatebot.com/diffs/npm/react-router-dom/5.2.0/5.3.4) | [![age](https://badges.renovateapi.com/packages/npm/react-router-dom/5.3.4/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/react-router-dom/5.3.4/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/react-router-dom/5.3.4/compatibility-slim/5.2.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/react-router-dom/5.3.4/confidence-slim/5.2.0)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>remix-run/react-router (react-router)</summary> ### [`v5.3.4`](https://togithub.com/remix-run/react-router/releases/tag/v5.3.4) [Compare Source](https://togithub.com/remix-run/react-router/compare/v5.3.3...v5.3.4) We removed the `mini-create-react-context` dependency, moving it into an internal module to eliminate peer dependency warnings for users on React 18 ([#​9382](https://togithub.com/remix-run/react-router/issues/9382)). **Full Changelog**: remix-run/react-router@v5.3.3...v5.3.4 ### [`v5.3.3`](https://togithub.com/remix-run/react-router/releases/tag/v5.3.3) [Compare Source](https://togithub.com/remix-run/react-router/compare/v5.3.2...v5.3.3) This release fixes a bad version selector in react-router-native. ### [`v5.3.2`](https://togithub.com/remix-run/react-router/releases/tag/v5.3.2) [Compare Source](https://togithub.com/remix-run/react-router/compare/v5.3.1...v5.3.2) - Fix: make v5 Router compatible with v18 StrictMode by [@​jgoz](https://togithub.com/jgoz) in [remix-run/react-router#8831 ### [`v5.3.1`](https://togithub.com/remix-run/react-router/releases/tag/v5.3.1) [Compare Source](https://togithub.com/remix-run/react-router/compare/v5.2.1...v5.3.1) This release adds missing `LICENSE` files to the published build. ### [`v5.2.1`](https://togithub.com/remix-run/react-router/releases/tag/v5.2.1) [Compare Source](https://togithub.com/remix-run/react-router/compare/v5.2.0...v5.2.1) This release fixes a bug with `<Link>` so that, when the `to` location is the same as the current, the history state entry is replaced instead of pushed to the stack. See [remix-run/react-router#5362 for details. 🥳 Thanks to [@​guidobouman](https://togithub.com/guidobouman) for the PR and for everyone else who weighed in for the fix! </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/sullivanpj/open-system).
Fixes #7870.
In React 18, Strict Mode attempts to detect unexpected side effects that might happen when rendering in concurrent mode. For class components, it intentionally double-invokes the constructor,
render()
, andshouldComponentUpdate()
. It also double-invokes both layout and passive effects by mounting, unmounting, and then remounting.Router in v5 was not compatible with this primarily because the main history subscription was created in the component constructor. Here is a simplified outline of the component lifecycle in StrictMode in v5.3.1:
At this point, there were no history subscriptions, so
setState
was never being invoked.The fix presented in this PR moves the main history subscription into componentDidMount to make it resilient to unmount/remount cycles. Here is the new simplified outline as of this PR:
The listener in the constructor is only used for detecting redirects caused by child mounts and the subscription is only active until componentDidMount, at which point it is disposed and replaced with the main listener. Since the main listener is attached in componentDidMount, it will be recreated if the component is unmounted and then remounted without being fully reconstructed.
Tests
Rather than changing the local react dependency to v18, I added synthetic tests that simulate the new StrictMode behavior. If the maintainers would prefer to see tests using actual rendering in v18, I'd be happy to amend this.