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

avatar
Borislav Hadzhiev

Last updated: Apr 6, 2024
3 min

banner

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

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

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

useroutes may be used only in 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 useRoutes hook in your App.js file.

App.js
import React from 'react'; import { useRoutes } from 'react-router-dom'; export default function App() { let element = useRoutes([ {path: '/', element: <Home />}, {path: '/about', element: <About />}, ]); return element; } function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; }

using use routes hook in your app js file

The code for this article is available on GitHub

The error occurs because the useRoutes 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.

# Using a component instead of objects to wrap your routes

The useRoutes hook is the functional equivalent of Routes, so you can also use a component instead of objects to define your routes.

App.js
import React from 'react'; import {BrowserRouter as Router, Route, Link, Routes} from 'react-router-dom'; export default function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> </ul> </nav> {/* ๐Ÿ‘‡๏ธ Wrap your Route components in a Routes component */} <Routes> <Route path="/about" element={<About />} /> <Route path="/" element={<Home />} /> </Routes> </div> </Router> ); } function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; }

using component instead of objects to wrap your routes

The code for this article is available on GitHub

React router uses a simplified path format where <Route path> has 2 kinds of placeholders:

  • dynamic :id params
  • * wildcards

The * wildcard syntax can only be used at the end of a path.

App.js
import React from 'react'; import {BrowserRouter as Router, Route, Link, Routes} from 'react-router-dom'; import {useParams} from 'react-router-dom'; export default function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <li> {/* ๐Ÿ‘‡๏ธ link to dynamic path */} <Link to="/users/4200">Users</Link> </li> <li> {/* ๐Ÿ‘‡๏ธ link to catch all route */} <Link to="/does-not-exist">Catch all route</Link> </li> </ul> </nav> {/* ๐Ÿ‘‡๏ธ Wrap your Route components in a Routes component */} <Routes> <Route path="/about" element={<About />} /> {/* ๐Ÿ‘‡๏ธ handle dynamic path */} <Route path="/users/:userId" element={<Users />} /> <Route path="/" element={<Home />} /> {/* ๐Ÿ‘‡๏ธ only match this when no other routes match */} <Route path="*" element={ <div> <h2>404 Page not found etc</h2> </div> } /> </Routes> </div> </Router> ); } function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; } function Users() { const params = useParams(); return <h2>Users: {params.userId}</h2>; }

wildcard syntax can only be used at end of path

The code for this article is available on GitHub

The route <Route path="/users/:userId" element={<Users />} /> uses a dynamic userId parameter, which we can access by using the useParams hook.

The route would match anything after /users/, e.g. /users/123 or /users/asdf.

The route that has a path equal to * serves as a catch-all route. It only matches when no other routes do.

For more examples, refer to the official docs page of React Router.

I've also written a detailed guide on how to handle 404 page not found in React Router.

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