Lesson 22 +10 XP

Effect Cleanup Functions

Effect Cleanup Functions

Some side effects set up standing resources (like timers, event listeners, or WebSockets) that continue running even after a component unmounts. To prevent memory leaks, React allows effects to return a cleanup function.

Why Cleanup is Essential

If a component sets an interval timer or window listener and then unmounts without cleaning it up, the callback continues executing in the background, consuming memory and attempting to update unmounted components.

Writing a Cleanup Function

Return a function from inside your useEffect callback. React executes this cleanup function:

  1. Right before the component unmounts from the DOM.
  2. Before running the effect again on subsequent renders (when dependencies change).
import { useState, useEffect } from 'react';

function WindowResizeListener() {
  const [windowWidth, setWindowWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWindowWidth(window.innerWidth);

    // 1. Setup subscription
    window.addEventListener('resize', handleResize);

    // 2. Return cleanup function
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []); // Setup once on mount, cleanup on unmount

  return <p>Window width: {windowWidth}px</p>;
}

Cleaning Up Timers & Subscriptions

function TimerComponent() {
  useEffect(() => {
    const timerId = setInterval(() => {
      console.log("Tick...");
    }, 1000);

    // Cleanup interval on unmount
    return () => clearInterval(timerId);
  }, []);

  return <div>Timer running...</div>;
}

Summary & TL;DR

  • Return a function from useEffect to define cleanup logic.
  • React runs the cleanup function when the component unmounts or before re-running the effect.
  • Essential for clearing intervals (clearInterval), removing event listeners (removeEventListener), and canceling active network subscriptions.