Skip to content
tezvyn:

Explain useEffect dependency array behavior for [], [deps], and omitted

Source: react.devEasyHow cards are made

Explain useEffect dependency array behavior for [], [deps], and omitted

It tests reactive dependency tracking. Omitting re-runs every render; [] runs on mount with cleanup on unmount; [deps] re-runs when Object.is detects change. Red flag: claiming [] means 'run once' without mentioning cleanup or stale values.

What's really being asked

This question checks if you know how React decides when to run an Effect, not just the API syntax. The interviewer wants to see that you think in terms of reactive dependencies and commit phases, not just memorized rules. They are listening for whether you treat Effects as synchronization with an external system rather than lifecycle methods.

The full answer

First, omitting the dependency array entirely means React has no snapshot to compare against, so the Effect runs after every single render commit. Second, passing an empty array [] tells React to compare against a stable empty snapshot, so the setup function runs only after the initial mount; the cleanup function runs when the component unmounts, and in Strict Mode the setup-cleanup cycle may execute twice to help detect side effects. Third, passing a populated array like [serverUrl, roomId] means React performs an Object.is comparison between the current and previous render values for each dependency; if any value changed, React first runs the cleanup from the previous render with old values, then runs the setup with new values. Fourth, you should mention that the dependency list must be written inline, have a constant number of items, and include every reactive value read inside the setup code.

The mistakes people make

A major red flag is saying that [] means the Effect runs exactly once and nothing else happens. This ignores cleanup, ignores that the Effect may re-run in development under Strict Mode, and invites stale closure bugs if you read reactive values that were omitted from the array. Another red flag is claiming that omitting the array is the same as passing []; it is not, because no array means no dependency check at all. A third red flag is failing to mention Object.is comparison or describing the check as deep equality; React uses Object.is, which is shallow and reference-based for objects and functions.

What usually comes next

The interviewer may ask how you would handle a function or object dependency that changes on every render without being semantically different. They might ask why the React linter enforces exhaustive-deps and what happens if you lie to it. They could also ask when you would use useLayoutEffect instead, or how to refactor an Effect that fetches data based on props.

A concrete example

Imagine a ChatRoom component with props roomId and state serverUrl. If you write useEffect with [roomId], the Effect re-connects to a new chat room whenever roomId changes, but it reads a stale serverUrl if serverUrl is not in the array. If you write useEffect with [], it connects once on mount using the initial roomId and serverUrl, never updates when the user switches rooms, and disconnects on unmount. If you omit the array entirely, it disconnects and reconnects after every keystroke or state update, which is usually wasteful and can cause performance problems or dropped connections.

Interview question

What happens to a useEffect's cleanup and setup when a value in its dependency array changes?

  • a.React runs the previous cleanup with old values first, then runs setup with the new valuesCorrect
  • b.React runs setup with the new values first, then runs the previous cleanup with old values
  • c.React checks if the dependency array itself is a new reference to decide whether to re-run
  • d.Cleanup only runs when the component unmounts, so only setup runs with the new values
Why?

React always runs the previous effect's cleanup with the old dependency values before running the new setup when a dependency changes. The most tempting distractor is wrong because cleanup is not reserved for unmount; it runs whenever dependencies change to prevent stale subscriptions or leaks.

Just read this? Test yourself on what you have been reading.

Read the original → react.dev

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on react — each one lists the topics its interview covers.

See open roles