The dependency array tells React when to re-run the effect. There are three cases:
- No array: the effect runs after every commit, meaning the first render and every re-render.
- Empty array
[]: it runs once after the component mounts. Its cleanup runs on unmount. - Values
[a, b]: it runs after mount, and again after any render where at least one dependency changed. React compares each one withObject.is.
A commit is the step where React applies the changes to the real DOM.
The array is not a way to choose when you want the effect to run. It must list every reactive value the effect reads. A reactive value is anything that can change between renders: props, state, and anything computed from them inside the component. The react-hooks/exhaustive-deps lint rule enforces this.
Sometimes a dependency changes too often. Then change the code rather than leaving the dependency out. For example, move an object inside the effect, or use an updater function.
In development with StrictMode, React runs setup, cleanup and setup again on mount. This helps you find missing cleanup.
- With no array, the effect runs after every render. With
[], only on mount. With[a, b], when any of them changes. - React compares dependencies with
Object.is. - You must list every reactive value the effect reads. The linter enforces this.
- Fix dependencies that change too often by restructuring the code, not by leaving them out.
- StrictMode runs an extra setup and cleanup cycle in development.