React useEffect is not triggering on route change

22,121

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.

Share:
22,121
Erik Martín Jordán
Author by

Erik Martín Jordán

Software engineer from beautiful Barcelona.

Updated on May 11, 2022

Comments

  • Erik Martín Jordán
    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
      sigmus over 4 years
      Where is your <Router> component?
    • Erik Martín Jordán
      Erik Martín Jordán over 4 years
      On index.js (question updated).
  • Erik Martín Jordán
    Erik Martín Jordán over 4 years
    Understood. Good answer.
  • Sonic Soul
    Sonic Soul over 3 years
    this 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
    Mohamed Ramrami over 3 years
    @SonicSoul Could you open a new question with your code ? Seems like a different issue.
  • Vishal Shori
    Vishal Shori over 3 years
    You made my day.Thanks you so much
  • Johan Mendez
    Johan Mendez almost 3 years
    Cleanest solution to be honest, however my key was a prop to be SSR safe, thanks Aliens
  • PedroPovedaQ
    PedroPovedaQ almost 3 years
    This should be the top solution. Awesome.
  • Stephane
    Stephane over 2 years
    Use this as of 2021 Router V6 stackoverflow.com/a/62389224/2394052