'Uncaught Error: useNavigate() may be used only in the context of a <Router> component. - What is it that I am doing wrong?
I am trying to create an authenticated route and I did the following but this throws an error saying
2Transition.js:251 Uncaught Error: useNavigate() may be used only in the context of a <Router> component.
at invariant (Transition.js:251:1)
at useNavigate (TransitionGroup.js:123:1)
at App (App.tsx:27:1)
at renderWithHooks (react-dom.development.js:17415:1)
at mountIndeterminateComponent (react-dom.development.js:22173:1)
at beginWork (react-dom.development.js:23654:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:5344:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:5393:1)
at invokeGuardedCallback (react-dom.development.js:5456:1)
at beginWork$1 (react-dom.development.js:28649:1)
What is it that I am doing wrong?
import { BrowserRouter, Routes, Route, useNavigate } from "react-router-dom";
function App() {
const navigate = useNavigate();
return(
<BrowserRouter>
<Routes>
<Route
path={APP_ROUTES.DASHBOARD}
element={
isUserLoggedIn() ? <Dashboard /> :
<>pp{navigate(APP_ROUTES.LOGIN)}</>
}
/>
</Routes>
</BrowserRouter>
)
}
What would be the best way to add a couple of authenticated routes?
Solution 1:[1]
You are trying to use useNavigate() inside the App's component that is not inside a BrowserRouter because the BrowserRouter is inside the App's component and not around.
Solution 2:[2]
As the error suggests, you are using a hook in a component that isn't inside the <BrowserRouter>.
A potential solution would be to build a ProtectedRoute component
const ProtectedRoute = ({ children }) => {
if (! isUserLoggedIn()) {
return <Navigate to={APP_ROUTES.LOGIN} replace />;
}
return children;
};
and wrap your route around it:
<Route
path="home"
element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
}
/>
Good blog post here: https://www.robinwieruch.de/react-router-private-routes/
Solution 3:[3]
Issue
The App component is rendering the router that provides the routing context that the useNavigate hook needs.
Solution
Move BrowserRouter higher in the ReactTree so that it can provide a routing context to components below it. Wrapping App component with a router is correct if you want to use any react-router-dom hooks in the App component.
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
...
import { Routes, Route, useNavigate } from "react-router-dom";
function App() {
const navigate = useNavigate();
return (
<Routes>
<Route
path={APP_ROUTES.DASHBOARD}
element={isUserLoggedIn()
? <Dashboard />
: <>pp{navigate(APP_ROUTES.LOGIN)}</>
}
/>
</Routes>
);
}
Additional Question
What would be the best way to add a couple of authenticated routes?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Benmax |
| Solution 2 | Squiggs. |
| Solution 3 | Drew Reese |
