What is the useEffect Dependency Array?
Learn how the useEffect dependency array works in React, the three array forms, Object.is comparison, stale closures, cleanup timing and common mistakes.
Expected Interview Answer
The useEffect dependency array is the second argument to useEffect that tells React which values the effect depends on, so React only re-runs the effect when one of those values changes between renders.
React compares each dependency to its previous value using Object.is after every render. If any value differs, the effect's cleanup runs and then the effect runs again. An empty array [] means run once after mount, no array means run after every render, and a populated array [a, b] means run whenever a or b changes. Omitting a value the effect actually uses causes stale closures and bugs.
- Prevents unnecessary re-runs of side effects
- Avoids infinite render loops
- Keeps effect logic in sync with current state and props
- Makes data-fetching and subscriptions predictable
- Enables correct cleanup timing
AI Mentor Explanation
Think of a coach who only calls a team meeting when the match situation genuinely changes — a wicket falls or the required run rate shifts. The dependency array is that trigger list: the effect (meeting) fires only when a listed value moves, not on every single delivery bowled.
Step-by-Step Explanation
Step 1
Write the effect
Place your side effect (fetch, subscription, timer) inside useEffect's callback.
Step 2
List real dependencies
Add every prop, state, or value the effect reads to the array so it stays in sync.
Step 3
Understand the comparison
React uses Object.is to compare each dependency to its previous value after each render.
Step 4
Choose the array shape
Use [] for run-once, [a,b] for run-on-change, or omit it for run-every-render.
Step 5
Add cleanup
Return a cleanup function; React runs it before re-running the effect and on unmount.
What Interviewer Expects
- Knows the three array forms and their behavior
- Understands Object.is dependency comparison
- Can explain stale closures from missing dependencies
- Knows why object/function deps cause extra runs
- Mentions cleanup timing relative to dependency changes
Common Mistakes
- Leaving out a value the effect actually uses, causing stale data
- Passing an inline object or function that changes every render
- Using [] but reading changing state inside, freezing the closure
- Confusing 'no array' with an empty array
- Suppressing the exhaustive-deps lint rule instead of fixing the cause
Best Answer (HR Friendly)
“The dependency array is a short list you give React telling it which pieces of data an effect cares about. React only re-runs that effect when something on the list actually changes, which keeps the app efficient and free of infinite loops.”
Code Example
import { useEffect, useState } from 'react'
function Profile({ userId }) {
const [user, setUser] = useState(null)
useEffect(() => {
let active = true
fetch(`/api/users/${userId}`)
.then((res) => res.json())
.then((data) => {
if (active) setUser(data)
})
return () => {
active = false
}
}, [userId])
return <p>{user ? user.name : 'Loading...'}</p>
}Follow-up Questions
- What is the difference between [] and omitting the array entirely?
- How do you handle object or function dependencies that change each render?
- What is a stale closure and how does it relate to dependencies?
- When does the cleanup function run relative to a dependency change?
- Why does the exhaustive-deps ESLint rule exist?
MCQ Practice
1. What does an empty dependency array [] mean for useEffect?
An empty array means the effect has no dependencies, so React runs it once after the initial mount and cleans up on unmount.
2. How does React decide whether to re-run an effect?
React compares each dependency to its previous value using Object.is; if any differs, the effect re-runs.
3. What commonly causes an effect to run on every render unexpectedly?
Inline objects and functions get a new reference each render, so Object.is sees them as changed and re-runs the effect.
Flash Cards
What does [] mean? — Run the effect once after mount and clean up on unmount.
What does omitting the array mean? — Run the effect after every render.
How are dependencies compared? — React uses Object.is on each dependency versus its previous value.
Why do inline objects cause extra runs? — They get a new reference each render, so Object.is treats them as changed.