A missing dependency in useEffect's dependency array causes a stale closure bug: the effect captures an outdated value of a variable and continues using it even after the variable has changed. This is one of the most common React bugs and is caught by the react-hooks/exhaustive-deps ESLint rule.
Why it happens
- •A prop or state variable used inside useEffect is omitted from the dependency array.
- •A function used inside useEffect is recreated on every render but not included in deps.
- •Using an empty dependency array ([]) but reading props or state inside the effect.
Examples
Code that triggers the error
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser(userId).then(setUser);
}, []); // userId missing from deps arrayError output
// ESLint warning: React Hook useEffect has a missing dependency: 'userId'. // Bug: profile never refreshes when userId prop changes.
How to fix it
Add all variables referenced inside useEffect to the dependency array. If the lint rule flags a function, move the function inside the effect or wrap it in useCallback. The empty array ([]) is only correct when the effect truly should run once and uses no reactive values.
Fixed code
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser(userId).then(setUser);
}, [userId]); // re-runs when userId changesRelated errors
Ready to practice your English at work?
Lingua-e has interactive exercises built around real developer conversations: standups, code reviews, retrospectives, and more. Practice until it comes naturally.
Try Lingua-e for free