Side Effects with useEffect

Run code that reaches outside React — timers, the document title, subscriptions — after a render, and control when it runs with the dependency array.

Step 1 of 2

Talking to the world outside React

So far your components just calculate JSX from props and state — pure and predictable. But real apps also need to reach outside: set the browser tab title, start a timer, focus an input, connect to a chat server, save to localStorage. These are side effects — work that isn't "return the UI."

You can't do that work directly in the component body, because React runs that code on every render and you'd fire the effect over and over. The useEffect hook gives effects a proper home: React runs them after it has updated the screen.

useEffect(() => {
  document.title = "Clicked " + count + " times";
}, [count]);

The second argument — [count] — is the dependency array. It tells React "only re-run this effect when count changes." That control is the whole point.

Think of it this way: A component's job is to paint the picture. An effect is the chore you do after hanging the painting: turn on the gallery light, update the little plaque, start the background music. The dependency array is your note saying "only redo the plaque if the painting's title changed."
Web Standard — the dependency array
  • [count] — run after renders where count changed.
  • [] — run once, after the first render (great for setup like starting a timer).
  • No array at all — run after every render (rarely what you want).
Tip — clean up after yourself

If your effect starts something ongoing (a setInterval, an event listener, a connection), return a function from it that stops it. React runs that cleanup before the next effect and when the component is removed: return () => clearInterval(id);