useEffect() is a side-effect management hook in React. It lets you perform operations like:
- Fetching data from an API
- Subscribing to events
- Updating the DOM
- Setting timers
All things you’d usually do in class components inside componentDidMount, componentDidUpdate, and componentWillUnmount.
📦 Syntax:
useEffect(() => {
// side-effect code
return () => {
// optional cleanup code (like removing event listeners)
};
}, [dependencies]);
🧠 How It Works:
- Runs after the component renders.
- The dependency array
[ ]tells React when to run the effect.
🧪 Usage Scenarios:
✅ 1. Run once on mount
useEffect(() => {
console.log("Mounted");
}, []);
🔁 2. Run on state/prop change
useEffect(() => {
console.log("Count changed:", count);
}, [count]);
🧹 3. Cleanup on unmount
useEffect(() => {
const timer = setInterval(() => console.log("Running..."), 1000);
return () => clearInterval(timer); // cleanup
}, []);
🔍 Analogy:
Think of useEffect as React saying:
“Hey, I just painted the UI. Now what side tasks should I run?”
⚠️ Common Mistakes:
- Forgetting the dependency array → runs on every render.
- Incorrect dependency list → causes unexpected behavior.
- Using async directly inside
useEffect(wrap it in a function instead).
✅ Best Practice:
useEffect(() => {
async function fetchData() {
const res = await fetch("/api");
const data = await res.json();
setData(data);
}
fetchData();
}, []);