useEffect Dependency Array

The dependency array tells React when an effect should be re-executed based on the reactive values it reads. It helps keep effects synchronized with changing props, state, and other reactive values.

`useEffect` runs an effect after rendering, and its dependency array controls which changes should cause that effect to run again. React compares each dependency with its previous value using `Object.is`.

With no dependency array, the effect runs after every completed render. With an empty array, the effect does not re-run because of later prop or state changes. With dependencies such as `[userId]`, the effect re-runs when `userId` changes.

Dependencies should reflect the reactive values used by the effect. In component code, props, state, and values declared in the component body are commonly reactive and may need to be included when referenced by the effect.

A dependency array does not make an effect run before rendering, and it does not manually control rendering. Effects are primarily for synchronizing a component with systems outside React, such as subscriptions, timers, browser APIs, or network-related synchronization.

If an effect subscribes to something using a dependency, its cleanup should generally undo the previous synchronization before the effect is set up again. This prevents stale subscriptions, timers, or other resources from accumulating.

Key points

Interview questions

What does the dependency array in `useEffect` do?

It tells React which reactive values the effect depends on. When one of those values changes, React runs the effect again after rendering. React compares dependency values with their previous values using `Object.is`. The list should correspond to the reactive values that the effect reads.

What is the difference between no dependency array, `[]`, and `[value]`?

Without a dependency array, the effect runs after every completed render. With `[]`, it does not re-run because of later changes to props or state. With `[value]`, it runs after the initial setup and whenever `value` changes according to React's dependency comparison. Cleanup runs when the existing effect is being replaced or removed.

Why should an effect include values that it reads from the component?

An effect should stay synchronized with the reactive values it uses. If a changing value is omitted, the effect can continue using an older value and become stale. Including the dependency gives React a signal to refresh the synchronization when that value changes. The exact dependency behavior can also be checked with the React Hooks linting rules.

Why can an object or function dependency cause an effect to run more often than expected?

React compares dependencies by `Object.is`, so two separately created objects or functions are usually different references even if their contents or behavior look equivalent. If such a value is recreated on each render, the dependency can appear changed on each render. That can cause the effect to re-run repeatedly. The solution is usually to reconsider the effect's design rather than blindly suppressing dependency warnings.

When should you avoid using `useEffect`?

An effect is unnecessary when the work can be performed directly during rendering or in an event handler without synchronizing with an external system. For example, a value derived from props or state usually does not need an effect and a second piece of state. Avoiding unnecessary effects reduces extra renders, dependency complexity, and synchronization bugs. Effects are most appropriate when React needs to coordinate with something outside React's rendering model.