Topic 28 of 54
Preventing Leaks
Overview
Some effects create resources that continue running in the background, like a `setInterval` timer or a WebSocket subscription. If the component is removed from the screen (unmounted), that timer keeps running forever, causing a Memory Leak. To prevent this, your effect can return a 'Cleanup Function'. React will run this cleanup function before the component unmounts, or before the effect runs again.
Syntax
If you navigate away from the page without the cleanup function, the interval keeps ticking in the background, consuming RAM and potentially crashing the app if it tries to update state on an unmounted component.
Returning a Cleanup Function
jsx
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
// SETUP Phase
const intervalId = setInterval(() => {
setSeconds(s => s + 1);
}, 1000);
// CLEANUP Phase (Returned as a function)
return () => {
clearInterval(intervalId); // Stop the timer when component is removed
};
}, []);
return <div>Timer: {seconds}s</div>;
}Common Pitfalls
- Forgetting to remove `window` or `document` event listeners, causing the same listener to be attached multiple times every time the component re-renders.
Interview Tips
- Cleanup functions are the functional equivalent of `componentWillUnmount` from the old Class component days. They are essential for removing event listeners and canceling network requests.
Real-World Example
Listening to global window events like resizing or scrolling.
example
jsx
function WindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
// Attach listener
window.addEventListener('resize', handleResize);
// Cleanup listener to prevent memory leaks
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return <p>Window is {width}px wide</p>;
}