Alex Sidorenko

A Visual Guide to useEffect - Cleanups

December 21, 2021

This is a second chapter of the Visual Guide to useEffect

Here is a component that logs how many seconds have passed from the first time it’s rendered.

Effects may keep running after the component unmounts

Now let’s say we have two pages in our app. Only one of those pages has our component. Here is what happens when we switch between the pages.

The log keeps running after the component unmounts. How to prevent that?

Every effect may return a function that cleans up after it

React performs the cleanup when the component unmounts

React Docs - useEffect

Effects may accumulate with every execution

Let’s change our component to log how many seconds have passed from the last time it is rendered. We will need to remove the dependency array to run the effect after every re-render.

If we keep re-rendering the component, we will keep creating new intervals. How do we only keep the last interval?

React also cleans up effects from the previous render before running the effects next time

React Docs - useEffect

When to use cleanups?

Whenever you add an effect, think about what will happen when the component unmounts. Will this effect keep running? If so, provide a cleanup function. If you do that, it will automatically cover the second use case when effects accumulate with every execution.

This effect won’t keep running after the component unmounts.
Doesn’t require a cleanup.

useEffect(() => {
  document.title = props.title
})

This effect will keep running after the component unmounts.
Requires a cleanup.

useEffect(() => {
  const handler = () => console.log(window.pageYOffset)
  window.addEventListener("scroll", handler);
  return () => window.removeEventListener("scroll", handler);
})