Skip to content

Conversation

@camd
Copy link
Collaborator

@camd camd commented Dec 21, 2025

Build on top of #9124

React Router v6 Migration Summary

Overview

This PR migrates from react-router-dom v5.1.2 to v6.x and removes the deprecated connected-react-router library.

Key Changes

Dependencies

Package Before After
react-router-dom 5.1.2 6.x
connected-react-router 6.9.3 Removed
history 4.10.1 Removed (bundled in v6)

API Changes

v5 Pattern v6 Pattern
<Switch> <Routes>
<Route render={() => <Comp />} /> <Route element={<Comp />} />
<Redirect to="/path" /> <Route element={<Navigate to="/path" />} />
useHistory() / history.push() useNavigate() / navigate()
props.match.path Relative paths
ConnectedRouter BrowserRouter

Files Modified

Redux Store Changes:

  • ui/job-view/redux/configureStore.js - Removed router middleware and reducer

Router Updates:

  • ui/App.jsx - Replaced ConnectedRouter + Switch with BrowserRouter + Routes
  • ui/push-health/App.jsx - Updated to v6 routing patterns
  • ui/perfherder/App.jsx - Updated to v6 routing patterns
  • ui/intermittent-failures/App.jsx - Updated to v6 routing patterns

Navigation Refactoring:

  • ui/job-view/App.jsx - Replaced pushRoute with useNavigate
  • ui/job-view/headerbars/SecondaryNavBar.jsx - Replaced pushRoute with useNavigate
  • ui/job-view/pushes/PushActionMenu.jsx - Replaced pushRoute with useNavigate
  • ui/job-view/redux/stores/selectedJob.js - Uses window.history.pushState for URL updates
  • ui/job-view/redux/stores/pushes.js - Uses window.history.pushState for URL updates
  • ui/models/filter.js - Accepts navigate function instead of Redux pushRoute

New Utilities:

  • ui/helpers/router.js - Centralized navigation hooks and utilities

Why This Migration?

  1. Deprecation: connected-react-router is deprecated and unmaintained
  2. React 18 Compatibility: React Router v6 is designed for React 18
  3. Smaller Bundle: v6 has a significantly smaller footprint
  4. Better Patterns: Hooks-based API aligns with modern React practices

Testing

  • All existing unit tests pass
  • Job View navigation works correctly
  • URL parameters and query strings preserved
  • Push Health routes accessible
  • Perfherder routes and redirects work
  • Browser back/forward navigation works
  • Deep linking works for all routes

@camd camd self-assigned this Dec 21, 2025
@camd camd force-pushed the camd/react-router-upgrade branch from 59583ba to c64c6a8 Compare December 21, 2025 19:52
@codecov-commenter
Copy link

codecov-commenter commented Dec 21, 2025

Codecov Report

❌ Patch coverage is 71.57360% with 392 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.21%. Comparing base (2248cd0) to head (a770a26).

Files with missing lines Patch % Lines
ui/job-view/pushes/Push.jsx 65.62% 72 Missing and 5 partials ⚠️
ui/job-view/headerbars/ActiveFilters.jsx 4.61% 61 Missing and 1 partial ⚠️
ui/job-view/App.jsx 73.62% 43 Missing and 5 partials ⚠️
...ermittent-failures/useIntermittentFailuresData.jsx 66.93% 36 Missing and 5 partials ⚠️
ui/job-view/pushes/FuzzyJobFinder.jsx 52.94% 31 Missing and 1 partial ⚠️
ui/job-view/pushes/PushJobs.jsx 70.73% 10 Missing and 2 partials ⚠️
ui/job-view/headerbars/SecondaryNavBar.jsx 88.17% 10 Missing and 1 partial ⚠️
ui/helpers/router.js 50.00% 9 Missing ⚠️
ui/intermittent-failures/MainView.jsx 52.63% 7 Missing and 2 partials ⚠️
ui/job-view/pushes/PushHeader.jsx 73.52% 8 Missing and 1 partial ⚠️
... and 26 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9134      +/-   ##
==========================================
+ Coverage   81.43%   82.21%   +0.78%     
==========================================
  Files         601      605       +4     
  Lines       33793    34030     +237     
  Branches     3067     3280     +213     
==========================================
+ Hits        27520    27979     +459     
+ Misses       6118     5720     -398     
- Partials      155      331     +176     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@camd camd force-pushed the camd/react-router-upgrade branch 2 times, most recently from cd39d89 to 9c5f93f Compare January 1, 2026 21:48
camd and others added 20 commits January 17, 2026 09:30
- Add tests/ui/App.test.jsx: Test URL transformations and routing
  - URL backwards compatibility (perf.html, pushhealth.html, logviewer.html)
  - Permalink hash preservation
  - Document title updates for perfherder alerts
  - Export verification (no react-hot-loader wrapper)

- Expand tests/ui/helpers/filter.test.js: Comprehensive filter helper tests
  - thMatchType, thFieldChoices, thFilterDefaults constants
  - arraysEqual and matchesDefaults functions
  - hasUrlFilterChanges URL comparison
  - reloadOnChangeParameters and allFilterParams arrays

- Add tests/ui/perfherder/App.test.jsx: Export and structure verification
  - Verify no hot loader wrapper (RSPack migration regression test)
  - Validate class component structure and lifecycle methods

- Add tests/ui/push-health/App.test.jsx: Component and routing tests
  - Component loading and API call verification
  - Route handling (push, my-pushes, usage)
  - Export verification for RSPack migration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change server command from 'yarn start' to 'pnpm start' to match
the package manager migration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tests for dayjs helper module (UTC, customParseFormat, isSameOrAfter, relativeTime plugins)
- Add tests for display.js dayjs migration (toMercurialDateStr, toMercurialShortDateStr)
- Add tests for taskcluster.js credential expiration with dayjs
- Add tests for DateRangePicker MUI component migration
- Add tests for intermittent-failures helpers (prettyDate, calculateMetrics)
- Add tests for perfherder helpers (getFilledBugSummary date formatting)
- Add tests for GraphsContainer and TableView date formatting
- Add tests for job-view App react-resizable-panels migration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add format:md, format:md:check, and lint:md scripts using prettier
- Fix lint errors in test files:
  - taskcluster.test.js: Use toThrow() instead of try/catch
  - DateRangePicker.test.jsx: Remove jest.mock with require(), use toHaveLength()
  - helpers.test.jsx: Use toHaveLength()
  - GraphsContainer.test.jsx: Remove unused variable

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tests/ui/App.test.jsx: Test URL transformations and routing
  - URL backwards compatibility (perf.html, pushhealth.html, logviewer.html)
  - Permalink hash preservation
  - Document title updates for perfherder alerts
  - Export verification (no react-hot-loader wrapper)

- Expand tests/ui/helpers/filter.test.js: Comprehensive filter helper tests
  - thMatchType, thFieldChoices, thFilterDefaults constants
  - arraysEqual and matchesDefaults functions
  - hasUrlFilterChanges URL comparison
  - reloadOnChangeParameters and allFilterParams arrays

- Add tests/ui/perfherder/App.test.jsx: Export and structure verification
  - Verify no hot loader wrapper (RSPack migration regression test)
  - Validate class component structure and lifecycle methods

- Add tests/ui/push-health/App.test.jsx: Component and routing tests
  - Component loading and API call verification
  - Route handling (push, my-pushes, usage)
  - Export verification for RSPack migration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change server command from 'yarn start' to 'pnpm start' to match
the package manager migration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive test coverage for changes introduced in the
defaultProps deprecation fixes:

- tests/ui/hooks/useDebounce.test.js: Tests for useDebouncedValue and
  useDebouncedCallback hooks (17 tests)
- tests/ui/hooks/useJobButtonRegistry.test.js: Tests for job button
  registry functions and hook lifecycle (25 tests)
- tests/ui/helpers/job.test.js: Tests for getBtnClass, isReftest,
  isPerfTest, canConfirmFailure, isClassified, isUnclassifiedFailure,
  findInstance, getResultState, addAggregateFields, getTaskRunStr,
  getTaskRun (57 tests)
- tests/ui/job-view/pushes/JobButton.test.jsx: Tests for the converted
  functional JobButton component (23 tests)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace require() with ES module import in job.test.js to fix global-require
- Use shorthand boolean attributes (visible, intermittent) in JobButton.test.jsx

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@camd camd force-pushed the camd/react-router-upgrade branch 2 times, most recently from 487d2e1 to aa37f61 Compare January 17, 2026 22:39
camd and others added 12 commits January 17, 2026 16:04
The withView HOC is a class component that expected location and history
props to be passed automatically by React Router. In React Router v6,
these are no longer passed - you must use hooks instead.

This caused the error: "Cannot read properties of undefined (reading 'state')"
at line 21: this.default = this.props.location.state || defaultState;

Fix by creating a ViewWithRouter wrapper component that:
- Uses useLocation() and useNavigate() hooks
- Injects location and navigate as props to the class component
- Creates a history-like object with push/replace for backwards compatibility

Also adds unit tests to verify the intermittent-failures routes render
correctly with React Router v6.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace the withView class-based Higher Order Component with a modern
useIntermittentFailuresData custom hook. This eliminates the need for
the ViewWithRouter wrapper and makes the code more readable and testable.

Changes:
- Create useIntermittentFailuresData.jsx custom hook that encapsulates
  all state management and data fetching logic
- Update MainView.jsx to use the hook directly instead of withView HOC
- Update BugDetailsView.jsx to use the hook directly instead of withView HOC
- Remove View.jsx (the old class-based HOC)
- Update tests to work with the new hook-based implementation

The hook uses:
- useState for state management (replacing this.state)
- useEffect for lifecycle (replacing componentDidMount)
- useCallback for memoized functions
- useRef for pending update tracking (replacing setState callbacks)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@camd camd force-pushed the camd/react-router-upgrade branch from aa37f61 to a770a26 Compare January 19, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants