This error occurs when the useNavigate hook from React Router is called in a component that is not wrapped within a Router provider (like BrowserRouter or MemoryRouter). The useNavigate hook requires access to React Router's context to function.
This error indicates that you're trying to use React Router's useNavigate hook in a component that doesn't have access to the Router context. In React Router v6+, hooks like useNavigate, useLocation, and useParams depend on context provided by Router components (BrowserRouter, HashRouter, MemoryRouter, etc.). The error typically occurs when: - The Router component is defined in the same file or component where you're using useNavigate - Your component tree isn't properly wrapped with a Router at the root level - You're testing components without wrapping them in a Router - You're using the hook in a utility function or class that's outside the component tree
The most common fix is to ensure your Router wraps your entire application at the root level. Move your Router component to your entry file (index.js, index.tsx, or main.tsx):
// src/index.js or src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);Now any component inside App can safely use useNavigate:
// src/App.js
import { useNavigate } from 'react-router-dom';
function App() {
const navigate = useNavigate();
const handleClick = () => {
navigate('/dashboard');
};
return <button onClick={handleClick}>Go to Dashboard</button>;
}
export default App;Verify that useNavigate is only used inside components that are children of your Router:
❌ Incorrect - Router inside component using the hook:
import { BrowserRouter, useNavigate } from 'react-router-dom';
function App() {
const navigate = useNavigate(); // ❌ Error! Router not yet mounted
return (
<BrowserRouter>
<div>Content</div>
</BrowserRouter>
);
}✅ Correct - Router wraps component using the hook:
import { BrowserRouter } from 'react-router-dom';
import Navigation from './Navigation';
function App() {
return (
<BrowserRouter>
<Navigation /> {/* ✅ Can use useNavigate */}
</BrowserRouter>
);
}
// Navigation.js
import { useNavigate } from 'react-router-dom';
function Navigation() {
const navigate = useNavigate(); // ✅ Works!
return <nav>...</nav>;
}When testing components that use useNavigate, wrap them in a Router (typically MemoryRouter for tests):
// Component.test.js
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import MyComponent from './MyComponent';
test('renders navigation button', () => {
render(
<MemoryRouter>
<MyComponent />
</MemoryRouter>
);
expect(screen.getByText('Navigate')).toBeInTheDocument();
});For multiple tests, create a custom render helper:
// test-utils.js
import { render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
export function renderWithRouter(ui, { route = '/' } = {}) {
window.history.pushState({}, 'Test page', route);
return render(
<MemoryRouter initialEntries={[route]}>
{ui}
</MemoryRouter>
);
}Then use it in tests:
import { renderWithRouter } from './test-utils';
test('my test', () => {
renderWithRouter(<MyComponent />);
});If you're using Storybook and your components use navigation hooks, add a router decorator:
// .storybook/preview.js
import { MemoryRouter } from 'react-router-dom';
export const decorators = [
(Story) => (
<MemoryRouter initialEntries={['/']}>
<Story />
</MemoryRouter>
),
];Or add it to individual stories:
// MyComponent.stories.jsx
import { MemoryRouter } from 'react-router-dom';
import MyComponent from './MyComponent';
export default {
title: 'MyComponent',
component: MyComponent,
decorators: [
(Story) => (
<MemoryRouter>
<Story />
</MemoryRouter>
),
],
};
export const Default = {
args: {},
};Navigation outside React components:
If you need to navigate programmatically from outside React components (like Redux thunks, API utilities, or event handlers), React Router v6 doesn't provide a built-in solution. You have a few options:
1. Pass navigate function as parameter:
// utils.js
export function logout(navigate) {
clearSession();
navigate('/login');
}
// Component.jsx
const navigate = useNavigate();
const handleLogout = () => logout(navigate);2. Create a custom history object (advanced):
// history.js
export const history = { navigate: null, location: null };
// App.jsx
import { useNavigate, useLocation } from 'react-router-dom';
import { history } from './history';
function HistoryHandler() {
history.navigate = useNavigate();
history.location = useLocation();
return null;
}
function App() {
return (
<BrowserRouter>
<HistoryHandler />
{/* rest of app */}
</BrowserRouter>
);
}
// Now you can use history.navigate('/path') anywhereRouter variants:
Different Router components for different use cases:
- BrowserRouter: Standard for web apps (uses HTML5 history API)
- HashRouter: Uses URL hash (#) for older browsers or static hosting
- MemoryRouter: Keeps history in memory (ideal for tests and React Native)
- StaticRouter: For server-side rendering
- NativeRouter: For React Native apps
React Router v7 changes:
React Router v7 introduced some breaking changes. If you upgraded and suddenly see this error:
- Ensure you're using the correct import paths
- Check that any third-party routing libraries (like Clerk) are compatible with v7
- Some packages may need their own Router setup - consult their migration guides
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite
Vite HMR connection failed, make sure your config is correct
How to fix "Vite HMR connection failed" in React