Begin react-router 5 → 6 migration via react-router-dom-v5-compat#381
Closed
blaipr wants to merge 2 commits into
Closed
Begin react-router 5 → 6 migration via react-router-dom-v5-compat#381blaipr wants to merge 2 commits into
blaipr wants to merge 2 commits into
Conversation
Stage 2 of the React stack modernization. react-router-dom 6/7 removed
Switch, useHistory, useRouteMatch, Redirect and withRouter, which 243
files here still use, so the migration has to be incremental. This sets
up the official bridge and migrates the first screen:
- Add react-router-dom-v5-compat (ships router v6 alongside v5) and
mount CompatRouter inside the app's HashRouter, so v5 and v6 routing
contexts coexist and components can be migrated file by file.
- Wire the v6 context into testUtils/enzymeHelpers: the v5 Router keeps
its history subscription and drives re-renders, while a fully
controlled nested v6 Router (location from v5 context, navigator =
the shared history) provides the v6 context without a second
subscription - no act() warnings, and shallow rendering still works.
- Migrate screens/Login as the demonstration slice: Redirect becomes
Navigate (from the compat package), and the withRouter wrapper is
dropped (the component never used the injected props).
- Remove a test.only in Login.test.js that had silenced the other 14
Login tests since the initial import, and fix the two assertions that
had rotted while dark (the custom login screen has no LoginMainHeader;
branding-fetch errors fall back to the default logo without a modal).
The suite now runs 2869 tests, 14 more than before.
Migration recipe for follow-up PRs, per component:
useHistory().push(x) -> useNavigate(); navigate(x)
useRouteMatch().params -> useParams()
<Redirect to={x} /> -> <Navigate to={x} />
withRouter(C) -> hooks (or delete if props unused)
importing from 'react-router-dom-v5-compat'; the root Switch in App.js
migrates last, then react-router-dom flips to v6 and the compat package
is removed.
This was referenced Jun 11, 2026
test_licenses requires every package.json dependency to have a matching file in licenses/ui (caught by an integration run of the full Python suite over all open PRs combined).
This was referenced Jun 11, 2026
Contributor
Author
|
Superseded by #392, which unifies the v5-compat bridge and all three migration batches into a single PR (one squashed commit, identical content, full gates green). Done as part of making the whole queue conflict-free and mergeable in any order. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📋 Merge instructions — all 13 open PRs, any order, zero conflicts
Every pair of open PRs has been verified conflict-free with
git merge-tree(0 conflicts across all 78 pairs), and the union of all 13 was integration-tested green (Python suite 3477 passed, Jest 2873 passed, lint, build, licenses). Merge in any order you like. Two recommendations, not requirements:The full queue:
SUMMARY
Stage 2 of the React stack modernization (stage 1 was #380).
react-router-dom6/7 removedSwitch,useHistory,useRouteMatch,RedirectandwithRouter— which 243 files in this codebase still use — so a big-bang upgrade isn't reviewable. This PR sets up React Router's official incremental-migration bridge and migrates the first screen:react-router-dom-v5-compatadded (ships router v6 alongside v5; works on React 17).CompatRouteris mounted inside the app'sHashRouter, so v5 and v6 routing contexts coexist and components can migrate file by file.testUtils/enzymeHelpersnow renders a nested controlled v6 Router (location from the v5 context, navigator = the shared history object) inside the v5 Router. The v5 Router keeps the only history subscription, so there are no duplicate-subscriptionact()warnings, shallow rendering still works, and tests for migrated components get the v6 context automatically.screens/Loginmigrated as the demonstration slice:<Redirect>→<Navigate>(compat package); thewithRouterwrapper is dropped — the component never read the injected props.Login.test.jscontained atest.onlydating to the initial import, which had silenced the other 14 Login tests ever since. It's removed, and the two assertions that rotted while dark are fixed (the custom login screen has noLoginMainHeader; branding-fetch errors fall back to the default logo without a modal). The suite now runs 2,869 tests — 14 more than before.Migration recipe for follow-up PRs (per component, importing from
react-router-dom-v5-compat)useHistory().push(x)const navigate = useNavigate(); navigate(x)useRouteMatch().paramsuseParams()<Redirect to={x} /><Navigate to={x} />withRouter(C)The root
SwitchinApp.jsmigrates last; thenreact-router-domflips to v6 and the compat package is removed.Independent of #374, #376, #377, #378 and #380 — mergeable in any order. Same caveat as the other UI PRs: each regenerates
package-lock.json, so later ones need a trivialnpm installregen.ISSUE TYPE
COMPONENT NAME
ASCENDER VERSION
ADDITIONAL INFORMATION
All UI gates run against exactly this branch state (unmodified main + only this change):