react router unmount function component

Naor picture Naor · May 15, 2019 · Viewed 7k times · Source

I am using React Router and have two routes that render the same component:

<Switch>
    <Route path="/aaa" component={Cmp} />
    <Route path="/bbb" component={Cmp} />
</Switch>

This is Cmp implementation:

class Cmp extends Component {
    componentWillUnmount() {
        console.log('******************* UNMOUNTED');
    }

    render() {
        return null;
    }
}

As I expect, navigating between /aaa and /bbb doesn't unmount Cmp.

I am moving to hooks so I rewrote the component:

function Cmp() {
    useEffect(() => {
        return () => {
            console.log('******************* UNMOUNTED');
        };
    });

    return null;
}

And very surprisingly, when running the app, navigating between /aaa and /bbb console.log that Cmp was unmounted.
Any idea how to prevent the unnecessary unmount-mount using function component and hooks?

Answer

Andrii Golubenko picture Andrii Golubenko · May 15, 2019

If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works. ...read more

Now your effect is called on every rerender of Cmp component. You have to pass the second argument with an empty array to useEffect if you want to call your effect only on unmounting:

useEffect(() => {
    return () => {
        console.log('******************* UNMOUNTED');
    };
}, []);