See my code below. I'm trying to add this button that goes back to the previous page using react-router-dom
but I get the below error, and also all the components on my website disappear.
Error:
useNavigate() may be used only in the context of a component
My code:
function App() {
const navigate = useNavigate();
return (
<BrowserRouter>
<div>
<button onClick={() => navigate(-1)}>go back</button>
<Nav/>
<Routes>
<Route exact path="/" element={<Home/>}/>
<Route exact path="/home" element={<Home/>}/>
<Route exact path="/upcoming/:user" element={<Upcoming/>}/>
<Route exact path="/record/:user" element={<Record/>}/>
<Route path="*" element={<NotFound/>}/>
</Routes>
</div>
</BrowserRouter>
);
}
And this is the error I got in console:
This error throws in useNavigate. useInRouterContext will check if the component(which uses useNavigate
hook) is a descendant of a <Router>
. If the component is not a descendant of the <Router>
component, it will throw this error.
Here's the source code to explain why you can't use useNavigate
, useLocation
outside of the Router
component:
useNavigate
usesuseLocation
underly,useLocation
will get the location from LocationContext provider. If you want to get the react context, you should render the component as the descendant of a context provider.Router
component use the LocationContext.Provider and NavigationContext.Provider. That's why you need to render the component as the children, so thatuseNavigate
hook can get the context data fromNavigationContext
andLocationContext
providers.
Your environment is browser, so you need to use BrowserRouter
. BrowserRouter
is built based on Router
.
Refactor to this:
App.jsx
:
function App() {
const navigate = useNavigate();
return (
<div>
<button onClick={() => navigate(-1)}>go back</button>
<Nav/>
<Routes>
<Route exact path="/" element={<Home/>}/>
<Route exact path="/home" element={<Home/>}/>
<Route exact path="/upcoming/:user" element={<Upcoming/>}/>
<Route exact path="/record/:user" element={<Record/>}/>
<Route path="*" element={<NotFound/>}/>
</Routes>
</div>
);
}
index.jsx
:
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.render(
<BrowserRouter>
<App/>
</BrowserRouter>,
document.getElementById('root')
)