Loading lessons...
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:
- Right before the component unmounts from the DOM.
- 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
useEffectto 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.