React Router v5 Compatibility Layer
The `react-router-dom-v5-compat` package provides a migration path for applications transitioning from React Router v4 or v5 to v6. It offers compatibility components and hooks that allow developers to run existing v5 routing logic within a v6 application environment. This enables incremental upgrades, avoiding a "big bang" rewrite. The package's current stable version is 6.30.3, aligning with the `react-router@6.x` series. While the core `react-router` project has progressed to v7, this compatibility layer remains focused on facilitating the v5-to-v6 migration. Its primary differentiator is enabling the co-existence of v5 and v6 routing paradigms, providing a temporary bridge rather than a permanent solution.
Common errors
-
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
cause Attempting to use `useCompatHistory` or other `useCompat` hooks outside of a component rendered within a `CompatRouter` context.fixEnsure that any component using `useCompatHistory` or similar compatibility hooks is a child of `CompatRouter` (or `BrowserRouter as CompatRouter`). -
Error: No routes matched location "/path"
cause This often indicates a mismatch between v5 and v6 routing configurations. For example, a v5 `CompatRoute` inside a v6 `Routes` without being nested in a `CompatSwitch` or `CompatRouter` that interprets v5 routes.fixVerify that v5 compatibility routes are correctly nested within `CompatRouter` and `CompatSwitch` components, and that the `path` props align with v5's exact/non-exact matching rules. -
TypeError: Cannot read properties of undefined (reading 'push')
cause Likely attempting to access `history.push` from `useCompatHistory` before the history object is properly initialized by the `CompatRouter` or outside its scope.fixConfirm that the component calling `useCompatHistory` is rendered within the component tree established by `CompatRouter`.
Warnings
- breaking This package is a temporary migration tool for React Router v6. It is not intended for long-term use and applications should aim for full migration to native React Router v6 (or later v7) constructs to leverage all performance and API benefits.
- gotcha Mixing `react-router-dom` v5 and v6 contexts and hooks directly can lead to unexpected behavior or runtime errors. Ensure that v5 compatibility components/hooks (e.g., `useCompatHistory`) are only used within a `CompatRouter` context.
- deprecated The underlying `react-router-dom` v5 itself is considered deprecated, with `react-router` having moved to v7. While `v5-compat` helps with the v6 transition, new development should target the latest stable version of `react-router-dom`.
Install
-
npm install react-router-dom-v5-compat -
yarn add react-router-dom-v5-compat -
pnpm add react-router-dom-v5-compat
Imports
- CompatRouter
import { CompatRouter } from 'react-router-dom-v5-compat'; // Incorrect aliasimport { BrowserRouter as CompatRouter } from 'react-router-dom-v5-compat'; - CompatSwitch
import { CompatSwitch } from 'react-router-dom-v5-compat'; // Incorrect aliasimport { Switch as CompatSwitch } from 'react-router-dom-v5-compat'; - useCompatHistory
import { useHistory } from 'react-router-dom-v5-compat'; // Ambiguous with v6's useNavigateimport { useHistory as useCompatHistory } from 'react-router-dom-v5-compat';
Quickstart
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import { BrowserRouter as CompatRouter, Switch as CompatSwitch, useHistory as useCompatHistory } from 'react-router-dom-v5-compat';
// A v5-style component
function OldHomePage() {
const history = useCompatHistory();
const handleClick = () => {
history.push('/old-about');
};
return (
<div>
<h2>Old Home Page (v5 compat)</h2>
<button onClick={handleClick}>Go to Old About</button>
<Link to="/v6-dashboard">Go to v6 Dashboard</Link>
</div>
);
}
// Another v5-style component
function OldAboutPage() {
return <h2>Old About Page (v5 compat)</h2>;
}
// A v6-style component
function V6Dashboard() {
return <h2>V6 Dashboard</h2>;
}
function App() {
return (
<Router>
<h1>Mixed React Router App</h1>
<Routes>
{/* v6 routes */}
<Route path="/v6-dashboard" element={<V6Dashboard />} />
<Route path="/" element={
<CompatRouter>
{/* v5 compatibility routes inside CompatRouter */}
<CompatSwitch>
<CompatRoute path="/old-about" component={OldAboutPage} />
<CompatRoute path="/" component={OldHomePage} />
</CompatSwitch>
</CompatRouter>
} />
</Routes>
</Router>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);