Skip to content

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:

  1. Upgrade React Router to a compatible version (v5.2.0+ if you need useHistory)
  2. 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:

bash
npm install react-router-dom@5.2.0

Your existing code will then work without changes:

jsx
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

jsx
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:

jsx
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:

jsx
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>
    </>
  );
}
jsx
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:

jsx
// 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 VersionRecommended HookStatus
v4.x and earlierNot applicableLegacy
v5.0.x - v5.1.xuseHistory (but may have issues)Update to v5.2.0+
v5.2.0 - v5.3.xuseHistoryStable
v6.x and lateruseNavigateCurrent

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.