useEffect is a React Hook that lets you perform side effects in functional components, such as fetching data, subscribing to events, or manually updating the DOM.
Sometimes, side effects need cleanup to avoid memory leaks or unexpected behavior, like when a component unmounts or before re-running the effect.
1️⃣ Basic useEffect Syntax
import React, { useEffect } from "react";
function MyComponent() {
useEffect(() => {
console.log("Effect runs");
// Optional cleanup function
return () => {
console.log("Cleanup runs");
};
}, []); // dependency array
return <div>Hello</div>;
}
2️⃣ When Cleanup Runs
- When the component unmounts
- Before the effect re-runs due to dependency changes
useEffect(() => {
const interval = setInterval(() => {
console.log("Tick");
}, 1000);
// Cleanup function
return () => {
clearInterval(interval); // prevents memory leak
console.log("Interval cleared");
};
}, []); // empty dependency → runs once
✅ Here, clearInterval stops the interval when the component unmounts.
3️⃣ useEffect with Dependencies
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Count changed:", count);
return () => {
console.log("Cleanup for previous count:", count);
};
}, [count]);
- Effect runs whenever
countchanges - Cleanup runs before the effect runs again (for the previous
count)
4️⃣ Common Use Cases for Cleanup
- Timers →
setInterval,setTimeout - Subscriptions → WebSocket, Firebase, Event listeners
- Abort fetch → Cancel API requests when component unmounts
useEffect(() => {
const handleScroll = () => console.log(window.scrollY);
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
⚡ In short:
useEffectruns side effects in React components. When an effect returns a cleanup function, React runs it before the next effect or on unmount, which helps prevent memory leaks and keeps behavior predictable.