Course outline · 0% complete

0/28 lessons0%

Course overview →

Cleanup functions

lesson 7-2 · ~12 min · 20/28

Cleanup functions

Some effects start something that must later be stopped: an interval keeps ticking, a subscription keeps listening, a websocket stays open. If the component unmounts or the dependencies change, the old work must be shut down. Otherwise it leaks: the timer or subscription keeps consuming memory and CPU for a component that no longer exists, and if its callback calls a state setter, React warns about updating an unmounted component.

The contract: whatever the effect returns is its cleanup function.

function ChatRoom({ room }) {
  useEffect(() => {
    const conn = connect(room);      // start
    return () => conn.close();       // stop
  }, [room]);
  return <h1>Room: {room}</h1>;
}

React runs cleanup at two moments:

  1. Before re-running the effect because a dependency changed, old room closes before the new one opens.
  2. At unmount, when the component leaves the screen.

So switching from room general to room random produces: subscribe general → unsubscribe general → subscribe random.

Code exercise · javascript

The cleanup contract in plain JavaScript. effect(room) starts a subscription and returns its own shutdown function, exactly like useEffect. Run it and match the output to: mount, dependency change, unmount.

Code exercise · javascript

Your turn. You get one dep value per render: ["a", "b", "b", "c"]. Complete the changed check so the effect only re-runs when the dep actually differs from the previous render, using Object.is like React does. The repeated "b" must be skipped.

Quiz

Spot the bug: ```jsx useEffect(() => { const id = setInterval(tick, 1000); }, []); ```