A cleanup function helps remove or undo things when a component stops showing on the screen. It keeps your app tidy and avoids problems like memory leaks.
Cleanup function in React
useEffect(() => {
// setup code here
return () => {
// cleanup code here
};
}, [dependencies]);The cleanup function is the function returned inside useEffect.
It runs before the component unmounts or before the effect runs again if dependencies change.
useEffect(() => {
const timer = setTimeout(() => {
console.log('Timer done');
}, 1000);
return () => {
clearTimeout(timer);
};
}, []);useEffect(() => {
function onResize() {
console.log('Window resized');
}
window.addEventListener('resize', onResize);
return () => {
window.removeEventListener('resize', onResize);
};
}, []);This component counts up every second. When it is removed from the screen, the cleanup function stops the counting interval and logs a message.
import React, { useState, useEffect } from 'react'; function TimerComponent() { const [count, setCount] = useState(0); useEffect(() => { const intervalId = setInterval(() => { setCount(c => c + 1); }, 1000); return () => { clearInterval(intervalId); console.log('Interval cleared'); }; }, []); return ( <div> <p>Count: {count}</p> </div> ); } export default TimerComponent;
Always use cleanup functions to avoid memory leaks and unexpected behavior.
Cleanup runs before the next effect if dependencies change, so it helps reset things properly.
Cleanup functions run when a component unmounts or before effects rerun.
They help remove timers, listeners, or subscriptions to keep apps healthy.
Use them inside useEffect by returning a function.
Practice
useEffect hook?Solution
Step 1: Understand the role of cleanup functions
Cleanup functions are used to tidy up side effects like timers or event listeners to prevent memory leaks.Step 2: Identify when cleanup runs
Cleanup runs when a component unmounts or before the effect runs again, ensuring resources are freed.Final Answer:
To remove timers, listeners, or subscriptions when the component unmounts or before the effect reruns -> Option BQuick Check:
Cleanup function purpose = Remove resources [OK]
- Thinking cleanup initializes state
- Confusing cleanup with data fetching
- Assuming cleanup runs after every render
useEffect?Solution
Step 1: Recognize cleanup function syntax
The cleanup function must be returned from the effect callback as a function.Step 2: Check each option
useEffect(() => { return () => { clearTimeout(timer); }; }, []); correctly returns a function that callsclearTimeout. Others either don't return a function or return the wrong value.Final Answer:
useEffect(() => { return () => { clearTimeout(timer); }; }, []); -> Option CQuick Check:
Cleanup function = returned function inside useEffect [OK]
- Not returning a function from useEffect
- Returning the result of cleanup call instead of a function
- Placing cleanup code outside the returned function
function Timer() {
React.useEffect(() => {
const id = setInterval(() => console.log('tick'), 1000);
return () => {
clearInterval(id);
console.log('cleanup');
};
}, []);
return null;
}Solution
Step 1: Understand the effect behavior
The effect sets an interval that logs 'tick' every second and returns a cleanup function that clears the interval and logs 'cleanup'.Step 2: Trace what happens on unmount
When the component unmounts, the cleanup runs once, clearing the interval and logging 'cleanup'.Final Answer:
'tick' every second and then 'cleanup' once when unmounting -> Option DQuick Check:
Interval logs 'tick'; cleanup logs 'cleanup' once [OK]
- Thinking cleanup runs repeatedly
- Confusing interval clearing with immediate stop
- Expecting no logs at all
useEffect(() => {
window.addEventListener('resize', handleResize);
return window.removeEventListener('resize', handleResize);
}, []);Solution
Step 1: Check cleanup function syntax
The cleanup must be a function returned from useEffect, not the result of calling removeEventListener immediately.Step 2: Identify correct cleanup pattern
The cleanup should be:return () => window.removeEventListener('resize', handleResize);to run on unmount.Final Answer:
The cleanup function should be a function returned, not the result of removeEventListener call -> Option AQuick Check:
Cleanup must be a returned function [OK]
- Calling cleanup immediately instead of returning a function
- Adding event listener inside cleanup
- Ignoring dependency array effects
function SocketComponent({ url }) {
React.useEffect(() => {
const socket = new WebSocket(url);
socket.onmessage = (event) => console.log(event.data);
// What cleanup code is correct?
}, [url]);
return null;
}Solution
Step 1: Understand cleanup for WebSocket
To avoid leaks, the socket must be closed when the component unmounts or URL changes.Step 2: Identify correct cleanup syntax
The cleanup must be a function returned from useEffect that callssocket.close(). return () => { socket.close(); }; does this correctly.Final Answer:
return () => { socket.close(); }; -> Option AQuick Check:
Cleanup returns function closing socket [OK]
- Calling close immediately instead of returning a function
- Returning the result of close() instead of a function
- Only nullifying event handlers without closing socket
Ready to prove it?
Pass the test and this pattern moves unknown
