
ReactJS
The unmounting phase is when a component is removed from the DOM. This is when you should clean up resources.
// ❌ BAD: Memory leak - listener never removed
function BadExample() {
React.useEffect(() => {
window.addEventListener("resize", () => {
console.log("Resized");
});
// No cleanup!
}, []);
return <div>Component</div>;
}
// ✅ GOOD: Cleanup prevents memory leak
function GoodExample() {
React.useEffect(() => {
const handleResize = () => console.log("Resized");
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return <div>Component</div>;
}React.useEffect(() => {
console.log("Effect setup");
// Cleanup function
return () => {
console.log("Effect cleanup");
};
}, []);
// Console when component mounts:
// "Effect setup"
// Console when component unmounts:
// "Effect cleanup"function WindowResizeListener() {
const [width, setWidth] = React.useState(window.innerWidth);
React.useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener("resize", handleResize);
// Cleanup
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return <div>Width: {width}</div>;
}function CountdownTimer() {
const [seconds, setSeconds] = React.useState(60);
React.useEffect(() => {
const timer = setTimeout(() => {
setSeconds(s => s - 1);
}, 1000);
// Cleanup
return () => clearTimeout(timer);
}, []);
return <div>{seconds}s remaining</div>;
}function NotificationListener() {
const [notifications, setNotifications] = React.useState([]);
React.useEffect(() => {
const subscription = notificationService.subscribe(newNotif => {
setNotifications(prev => [...prev, newNotif]);
});
// Cleanup
return () => {
subscription.unsubscribe();
};
}, []);
return <ul>{notifications.map(n => <li key={n.id}>{n.text}</li>)}</ul>;
}function UserDataFetcher({ userId }) {
const [user, setUser] = React.useState(null);
React.useEffect(() => {
const abortController = new AbortController();
fetch(`/api/users/${userId}`, {
signal: abortController.signal
})
.then(r => r.json())
.then(setUser);
// Cleanup - cancel request if component unmounts
return () => {
abortController.abort();
};
}, [userId]);
return <div>{user?.name}</div>;
}function CleanupTiming() {
React.useEffect(() => {
console.log("1. Setup");
return () => {
console.log("2. Cleanup before next effect");
};
}, []);
React.useEffect(() => {
console.log("3. Second setup");
return () => {
console.log("4. Second cleanup");
};
}, []);
}
// Mount output:
// 1. Setup
// 3. Second setup
// Unmount output:
// 2. Cleanup before next effect
// 4. Second cleanupResources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep • Build Real • Verify Skills • Launch Forward