useNavigate() may be used only in the context of a Router component

avatar
Borislav Hadzhiev

Last updated: Apr 6, 2024
3 min

banner

# useNavigate() may be used only in the context of a Router component

The error "useNavigate() may be used only in the context of a Router component" occurs when we try to use the useNavigate hook outside of the Router context in React Router.

To solve the error, use the useNavigate hook only within the Router context.

usenavigate may be used only in the context of router

Here is an example of wrapping your React app in a Router in your index.js file.

index.js
import {createRoot} from 'react-dom/client'; import App from './App'; import {BrowserRouter as Router} from 'react-router-dom'; const rootElement = document.getElementById('root'); const root = createRoot(rootElement); // ๐Ÿ‘‡๏ธ Wrap App in Router root.render( <Router> <App /> </Router> );
The code for this article is available on GitHub

Now you can use the useNavigate hook in your App.js file.

App.js
import React from 'react'; import { useNavigate, } from 'react-router-dom'; export default function App() { const navigate = useNavigate(); const handleClick = () => { // ๐Ÿ‘‡๏ธ navigate programmatically navigate('/about'); }; return ( <div> <button onClick={handleClick}>Navigate to About</button> </div> ); }

using use navigate hook in app js

The error occurs because the useNavigate hook makes use of the context that the Router component provides, so it has to be nested inside of a Router.

The best place to wrap your React app with a Router component is in your index.js file because that's the entry point of your React application.

Once your entire app is wrapped with a Router component, you can use any of the hooks from the React Router package anywhere in your components.

# (Jest) useNavigate() may be used only in the context of a Router component

The solution if you get the error while using the Jest testing library is the same, you have to wrap the component that uses the useNavigate hook in a Router.

App.test.js
import {render} from '@testing-library/react'; import App from './App'; import {BrowserRouter as Router} from 'react-router-dom'; // ๐Ÿ‘‡๏ธ Wrap component that uses useNavigate in Router test('renders react component', async () => { render( <Router> <App /> </Router>, ); // Your tests... });

jest usenavigate may only be used in context of router

The code for this article is available on GitHub
The useNavigate hook returns a function that lets us navigate programmatically, e.g. after a form is submitted.

The error is caused because the component we are testing or one of its children uses the useNavigate hook.

The useNavigate hook can only be used inside of a Router component because it makes use of the context that the Router provides.

If any of the components you are rendering in your test use the useNavigate hook, you have to wrap them in a Router when testing them.

# Using the equivalent of history.replace()

The parameter we passed to the navigate function is the same as the to prop on a <Link to="/about"> component.

If you want to use the equivalent of the history.replace() method, pass an options parameter to the navigate function.

App.js
import {useNavigate} from 'react-router-dom'; export default function App() { const navigate = useNavigate(); const handleClick = () => { // ๐Ÿ‘‡๏ธ replace set to true navigate('/about', {replace: true}); }; return ( <div> <button onClick={handleClick}>Navigate to About</button> </div> ); }

using equivalent of history replace method

The code for this article is available on GitHub

When the replace property is set to true on the options object, the current entry in the history stack gets replaced with the new one.

In other words, navigating to the new route won't push a new entry into the history stack, so if the user clicks the back button, they won't be able to navigate to the previous page.

This is useful, for example, when a user logs in - you don't want them to be able to click the back button and get back to the login page.

Or if you have a route that redirects users to a different page - you don't want users to click the back button and get redirected again.

You can also call the navigate function with a delta to go back in the history stack, e.g. navigate(-1) is the same as hitting the back button.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev