React Router useHistory vs useNavigate: Migrating to v6
Problem Statement
When working with React Router, you might encounter the error:
Attempted import error: 'useHistory' is not exported from 'react-router-dom'This error typically occurs when you're using React Router v6, which introduced breaking changes by replacing the useHistory hook with useNavigate. If your code was written for v5 or earlier versions, you'll need to update your imports and navigation methods.
Solution Overview
There are two main approaches to resolve this issue:
- Upgrade React Router to a compatible version (v5.2.0+ if you need
useHistory) - Migrate to React Router v6 and use the new
useNavigatehook
Solution 1: Using React Router v5.2.0+
If you need to maintain compatibility with your existing codebase, you can upgrade to React Router v5.2.0 or later, which includes the useHistory hook:
npm install react-router-dom@5.2.0Your existing code will then work without changes:
import { useHistory } from 'react-router-dom';
function MyComponent() {
const history = useHistory();
const handleClick = () => {
history.push('/home');
};
// Your component logic
}Solution 2: Migrating to React Router v6
For new projects or when updating existing ones, it's recommended to use React Router v6 with the useNavigate hook:
Basic Usage
import { useNavigate } from 'react-router-dom';
function MyComponent() {
const navigate = useNavigate();
const handleClick = () => {
navigate('/home');
};
// Your component logic
}Complete Migration Example
Here's how to convert the original problem code to use React Router v6:
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
// ... other imports
function UserForm() {
const [step, setStep] = useState(1);
const navigate = useNavigate(); // Replace useHistory with useNavigate
// ... other component logic
const confirm = (e) => {
navigate('/'); // Replace history.push with navigate
}
return (
// Your JSX
)
}
export default UserFormAdvanced Navigation Methods
In v5, useHistory provided several methods for navigation. Here's how to achieve the same functionality with v6:
import { useHistory } from "react-router-dom";
function App() {
const { go, goBack, goForward } = useHistory();
return (
<>
<button onClick={() => go(-2)}>Go 2 pages back</button>
<button onClick={goBack}>Go back</button>
<button onClick={goForward}>Go forward</button>
<button onClick={() => go(2)}>Go 2 pages forward</button>
</>
);
}import { useNavigate } from "react-router-dom";
function App() {
const navigate = useNavigate();
return (
<>
<button onClick={() => navigate(-2)}>Go 2 pages back</button>
<button onClick={() => navigate(-1)}>Go back</button>
<button onClick={() => navigate(1)}>Go forward</button>
<button onClick={() => navigate(2)}>Go 2 pages forward</button>
</>
);
}Additional Navigation Options
The navigate function in v6 supports several options:
// Replace current entry in history instead of adding a new one
navigate('/path', { replace: true });
// Pass state along with navigation
navigate('/path', {
state: {
user: 'JohnDoe',
data: {...}
}
});
// Relative navigation
navigate('../parent'); // Go up one levelVersion Compatibility Table
| React Router Version | Recommended Hook | Status |
|---|---|---|
| v4.x and earlier | Not applicable | Legacy |
| v5.0.x - v5.1.x | useHistory (but may have issues) | Update to v5.2.0+ |
| v5.2.0 - v5.3.x | useHistory | Stable |
| v6.x and later | useNavigate | Current |
WARNING
When upgrading from v5 to v6, be aware that there are other breaking changes beyond just the replacement of useHistory. Review the official migration guide for complete details.
Conclusion
The "useHistory is not exported from react-router-dom" error occurs when using v6 syntax with an older codebase or vice versa. The solution depends on your project requirements:
- For maintaining existing code: Upgrade to React Router v5.2.0+
- For new development: Use React Router v6 with
useNavigate
The useNavigate hook in v6 provides a more intuitive API and better alignment with modern React patterns, making it the recommended approach for new projects.
INFO
Always check your current React Router version using npm list react-router-dom before implementing these solutions to ensure you're using the correct approach for your specific version.