Side Effects with useEffect
Run code in response to rendering — timers, subscriptions, and (most importantly) fetching data.
What you will learn
- Use the useEffect hook
- Control when effects run with the dependency array
- Understand common use cases
Code that runs after render
useEffect runs code after the component renders. Its second argument — the dependency array — controls when it runs again.
| Dependency array | Runs |
|---|---|
[] (empty) | Once, after the first render |
[count] | After first render + whenever count changes |
| (omitted) | After every render (rarely what you want) |
function App() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const id = setInterval(() => setSeconds(s => s + 1), 1000);
return () => clearInterval(id); // cleanup
}, []); // run once
return <h2>Timer: {seconds}s ⏱️</h2>;
}Let us read the timer. useEffect(() => { ... }, []) runs its code once, right after the first render (because of the empty []). Inside, setInterval starts a repeating timer that calls setSeconds(s => s + 1) every 1000ms — each tick adds one to the state, so the number on screen climbs. The return () => clearInterval(id) is the cleanup: when the component is removed, React runs it to stop the timer so it does not leak. Without [], a new timer would start on every render — a classic bug.
Note: Output: Timer: 0s ⏱️, then Timer: 1s, Timer: 2s… counting up by one each second, forever, until the component is removed.
Tip: The return inside useEffect is a cleanup function — React runs it before the next effect or when the component is removed. Use it to clear timers and subscriptions.
Watch out: A wrong dependency array can cause infinite re-render loops. Start with [] for “run once” (like fetching data on load), and add only the values your effect truly depends on.
Q. What does an empty dependency array [] mean for useEffect?
✍️ Practice
- Build a counting-up timer with
useEffectandsetInterval(remember cleanup). - Use
useEffectwith[count]to log a message whenever a counter changes.
🏠 Homework
- Build a digital clock component that updates every second.