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
useNavigate
hook
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.0
Your 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 UserForm
Advanced 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 level
Version 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.