The dependency array in useEffect controls when the effect runs. It tells React which values to watch for changes before re-running the effect.
1️⃣ Syntax
useEffect(() => {
// effect code here
}, [dependencies]);
- The effect runs after every render where dependencies change
- Optional dependency array:
| Dependency Array | Behavior |
|---|---|
[] |
Runs once on mount |
[var1, var2] |
Runs when var1 or var2 changes |
| Not provided | Runs after every render |
2️⃣ Examples
Run once on mount
useEffect(() => {
console.log("Component mounted");
}, []);
- Useful for fetching data on load or adding event listeners
Run on specific state/prop changes
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Count changed:", count);
}, [count]);
- Effect runs only when
countchanges
Run on every render (no dependencies)
useEffect(() => {
console.log("Runs on every render");
});
- Avoid if the effect is heavy, as it can cause performance issues
3️⃣ Cleanup with Dependencies
- If your effect creates subscriptions, timers, or event listeners, always clean up:
useEffect(() => {
const interval = setInterval(() => console.log("tick"), 1000);
return () => clearInterval(interval); // cleanup on unmount or before next effect
}, []); // empty array → cleanup only on unmount
- If you include dependencies, cleanup runs before the next effect:
useEffect(() => {
console.log("Count updated:", count);
return () => console.log("Cleaning up previous effect");
}, [count]);
⚡ Key Points
- Always include all external variables used inside the effect in the dependency array
- Missing dependencies can lead to stale closures or bugs
- Empty array
[]→ effect runs once on mount - No array → effect runs after every render
In short:
The dependency array inuseEffectcontrols when the effect runs. Properly managing dependencies ensures accurate, efficient side effects and prevents unnecessary renders or stale state issues.