React · Frontend system thinking
How do you think about useEffect dependencies?
Short answer
Include every reactive value the effect reads: props, state and values derived from them. React compares dependencies with Object.is and re-runs the effect when one changes.
The dependency array is not a scheduling hint. It is the list of inputs the effect depends on. If the effect reads a value from the component scope and that value can change between renders, it belongs in the array. Omitting it lets the effect close over an old render's value.
function Room({ roomId, serverUrl }) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId, serverUrl]);
}What counts as reactive
- Props and state
- Values computed from props or state during render
- Functions declared in the component that close over reactive values
- Context values read with
useContext
Objects, arrays and functions get a new identity on every render. If an effect depends on one, it may re-run more often than expected. Move stable values outside the component, memoize them when appropriate, or restructure the effect so it depends on primitive inputs instead of a freshly created object.
function Search({ query }) {
useEffect(() => {
const id = setTimeout(() => {
searchApi(query);
}, 300);
return () => clearTimeout(id);
}, [query]);
return <input value={query} readOnly />;
}Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1What is the difference between an empty array and omitting the array?
- 2Why does an effect with an object dependency run on every render?
- 3Are functions stable between renders?
- 4How do you handle an effect that should read the latest value without re-subscribing?
Say it in the interview
I treat the dependency array as the effect's inputs. Anything reactive that the effect reads, including props, state, derived values and context, goes in the array. React compares entries with Object.is, so a new object or function identity can cause extra runs. If a dependency makes the effect run too often, I fix the effect or stabilise the value rather than suppressing the lint warning.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live React mock interview and get scored feedback on depth, clarity and confidence.