Effect Cleanup

How to prevent memory leaks and duplicate subscriptions by returning a cleanup function from your effects.

React3 min readConcept 16 of 46

What it is

When you write a useEffect, you can optionally return a function from it. This is called the **cleanup function**.

React will execute this cleanup function at two specific times: right before the component unmounts (is destroyed), and right before the effect re-runs due to a dependency changing.

Why it matters

Many side effects are persistent. If you call setInterval, the browser will keep ticking that timer forever until you explicitly call clearInterval.

If a component mounts, starts a timer, and then unmounts, the timer is still running in the background! This is a memory leak. Over time, your application will become sluggish and crash.

How to use it

Return an arrow function from your effect that undoes whatever the main body of the effect did.

tsx useEffect(() => { window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, []);

The Ghost Listeners

Mount and unmount the components repeatedly. The buggy component leaves behind a 'ghost' event listener every time it unmounts! The fixed component cleans up after itself.

// ❌ BUG: No cleanup returned
useEffect(() => {
window.addEventListener('scroll', log);
}, []);
 
// ✅ FIXED: Returns cleanup function
useEffect(() => {
window.addEventListener('scroll', log);
// React runs this right before unmount:
return () => {
window.removeEventListener('scroll', log);
};
}, []);
Buggy Subs0
Unmounted
Fixed Subs0
Unmounted

Mount and unmount the components repeatedly. Notice how the buggy component leaves behind an orphaned subscription every single time it unmounts (memory leak). The fixed component correctly cleans up its subscription when unmounted.

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1When does React execute the cleanup function returned by `useEffect`?
  2. 2You start a `setInterval` in an effect but forget to return a cleanup function. The user navigates to a different page and the component unmounts. What happens?
  3. 3Which of the following is the correct syntax for a cleanup function?

Remember this

  • Effects that set up subscriptions, timers, or event listeners require cleanup.
  • Return a function from your useEffect to act as the cleanup phase.
  • Cleanup runs before the component unmounts.
  • Cleanup also runs before the effect re-runs when a dependency changes.

Done with this concept?

Mark it complete to track your progress. No login needed.