useEffect
The useEffect hook runs a setup function after the component renders, re-running it when its dependencies change and calling an optional cleanup function before the next run or on unmount.
Definition
useEffect lets a component run code after it renders — the work that is not part of computing the JSX, such as starting a timer, subscribing to an event, setting the document title, or fetching data. You give it a setup function and a list of dependencies; React runs the setup after committing the render, and runs it again whenever a value in the dependency list has changed since the last time.
It is the effect companion to useState: where state is data a component holds, an effect is how a component reaches outside itself to synchronise with something else. For the wider picture of how components hold and change data, see React state — the basics.
Syntax
import { useEffect } from 'react';
useEffect(setup, dependencies);
useEffect(() => {
// setup: runs after render
return () => {
// cleanup: runs before the next setup / on unmount
};
}, [a, b]); // dependencies
Parameters
| Parameter | Description |
|---|---|
setup | The function React runs after the component renders. It contains your side-effect code — subscribing, timers, fetching, DOM work. It may return a cleanup function; if it returns nothing, there is no cleanup. |
dependencies | An optional array of reactive values (state, props, or anything derived from them) the setup depends on. React compares each value with the previous render using Object.is and re-runs the effect only when one has changed. Omit it and the effect runs after every render; pass [] and it runs only once, after the first render. |
React requires that the dependencies array include every reactive value the setup reads. Its development build warns when a dependency is missing, because a stale dependency list is the most common source of effect bugs.
Return value
useEffect itself returns nothing. What matters is the value your setup function returns — the optional cleanup — and how the dependencies array controls the timing:
- Cleanup function — if setup returns a function, React runs it before re-running the effect and once more when the component unmounts. Use it to undo whatever setup did: clear an interval, remove a listener, close a connection. Skipping cleanup is what causes duplicate timers and subscription leaks.
[](empty dependencies) — setup runs once after the first render, and cleanup runs once on unmount. This is the on-mount pattern.[a, b](with dependencies) — setup runs after the first render and again after any render whereaorbchanged; cleanup runs before each re-run using the values from the render that set it up.- No dependency array — setup runs after every render. This is rarely what you want and usually signals a missing array.
So the dependency array is not decoration — it is the entire schedule for when the setup and its cleanup fire. Get the array right and the effect stays synchronised with exactly the values it depends on.
Examples
An effect that runs once on mount
With an empty dependency array [], the setup runs a single time, right after the first render. Here it flips a status message once the component has mounted.
An interval with a cleanup function
This effect starts an interval on mount and returns a cleanup that clears it. Without the cleanup, every re-mount would leave another interval running — the classic leak the return value prevents.
Re-running when a dependency changes
// runs after the first render and after any render where `count` changed
useEffect(() => {
document.title = 'Count: ' + count;
}, [count]);
Browser & runtime support
useEffect has been available since React 16.8 and works in every modern version. Like all hooks it must be called at the top level of a component or custom hook. In development, React 18 and 19 intentionally mount, unmount and remount components once under Strict Mode, running your setup and cleanup an extra time — a deliberate check that your cleanup correctly undoes your setup, not a bug.
Frequently asked questions
What is the dependencies array in useEffect?
[] means run once on mount; omitting the array means run after every render.