React useEffect is not triggering on route change
Solution 1
The useEffect
is not triggered because the App
component is not re-rendered, nothing changed in that component (no state or props update).
If you want the App
component to re-render when the route change, you can use the withRouter
HOC to inject route props, like this :
import { Switch, Route, withRouter } from 'react-router-dom';
const App = () => {
useEffect( () => console.log('Refresh'));
return (...);
}
export default withRouter(App);
Example : https://codesandbox.io/s/youthful-pare-n8p1y
Solution 2
use the key attribute so everytime we render new component (different key)
<Route path='/mypath/:username' exact render= {routeProps =><MyCompo {...routeProps} key={document.location.href} />} />
Solution 3
Use the 2nd argument to useEffect to conditionally apply effect. For example via react-router-dom, you get some properties
const { schoolId, classId } = props
useEffect(() => {
// fetch something here
}, [schoolId, classId)
Here [schoolId, classId
acts as the unique identifier for useEffect to trigger.
Comments
-
Erik Martín Jordán about 2 years
I expect that
console.log('Refresh')
runs every time the route changes (switching from Component1 to Component2). But it's only triggering on first render. Why?index.js
:import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { BrowserRouter } from 'react-router-dom'; ReactDOM.render(<BrowserRouter><App /></BrowserRouter>, document.getElementById('root'));
App.js
:import React, { useEffect } from 'react'; import { Switch, Route } from 'react-router-dom'; import Nav from './Nav'; import Component1 from './Component1'; import Component2 from './Component2'; const App = () => { useEffect( () => console.log('Refresh')); return ( [<Switch> <Route component = {Nav}/> </Switch>, <Switch> <Route exact path = '/component1' component = {Component1}/> <Route exact path = '/component2' component = {Component2}/> </Switch>] ); } export default App;
Nav.js
:import React from 'react'; import { Link } from 'react-router-dom'; const Nav = () => { return ( <div> <Link to = '/component1'>Component 1</Link> <Link to = '/component2'>Component 2</Link> </div> ); } export default Nav;
Component1.js
:import React from 'react'; const Component1 = () => { return ( <div> <p>Hi</p> </div> ); } export default Component1;
Component2.js
:import React from 'react'; const Component2 = () => { return ( <div> <p>Bye</p> </div> ); } export default Component2;
-
sigmus over 4 yearsWhere is your
<Router>
component? -
Erik Martín Jordán over 4 yearsOn
index.js
(question updated).
-
-
Erik Martín Jordán over 4 yearsUnderstood. Good answer.
-
Sonic Soul over 3 yearsthis did not resolve my issue. in my case useEffect works as expected UNTIL i navigate to a different route, and come back to current route, and then useEffect doesn't fire, seems to happen regardless of listening to specific state var or not.
-
Mohamed Ramrami over 3 years@SonicSoul Could you open a new question with your code ? Seems like a different issue.
-
Vishal Shori over 3 yearsYou made my day.Thanks you so much
-
Johan Mendez almost 3 yearsCleanest solution to be honest, however my key was a prop to be SSR safe, thanks Aliens
-
PedroPovedaQ almost 3 yearsThis should be the top solution. Awesome.
-
Stephane over 2 yearsUse this as of 2021 Router V6 stackoverflow.com/a/62389224/2394052