React Effects and Effect Synchronization

React Effects synchronize a component with systems outside React, such as subscriptions, browser APIs, timers, or network connections. They are not the normal mechanism for deriving values during rendering.

An Effect is declared with `useEffect` and runs after React has committed a render. It can perform work that must interact with something external to React, such as connecting to a service, subscribing to events, or updating an imperative browser API.

A useful distinction is between rendering and synchronization. Rendering should calculate what the UI should look like from current props and state. If a value can be calculated directly during rendering, putting that calculation in an Effect usually adds an unnecessary render cycle and more state-management complexity.

An Effect can return a cleanup function. React calls cleanup before re-running the Effect when its dependencies change and when the component is removed. Cleanup is where subscriptions are unsubscribed, timers are cleared, or external connections are disconnected.

The dependency array describes which reactive values the Effect uses and therefore when React should re-synchronize it. Missing a required dependency can leave the Effect working with stale values, while unnecessary dependencies can cause synchronization to happen more often than intended.

For example, an Effect can synchronize a document title with component state because `document` is an external browser system. By contrast, calculating a filtered list from props during render does not require an Effect.

Key points

Interview questions

When should you avoid using useEffect?

You should generally avoid an Effect when the task is only to calculate data from existing props or state. That calculation can usually happen directly during rendering. Using an Effect for it often requires another state variable and creates an unnecessary update cycle. Event-specific logic also generally belongs in the event handler rather than an Effect.

Why does an Effect need a dependency array?

The dependency array tells React which reactive values the Effect depends on for synchronization. When one of those values changes, React can run the cleanup and synchronize again. Dependencies should correspond to reactive values referenced by the Effect. Omitting a necessary dependency can cause the Effect to observe an outdated value.

What problem are React Effects designed to solve?

Effects are designed to synchronize a React component with something outside React. Examples include browser APIs, subscriptions, timers, and external connections. They run after React has committed the render. They should not be treated as the default place for ordinary calculations.

What is Effect cleanup and when does it run?

Cleanup releases or reverses resources established by an Effect. Typical examples include removing event listeners, clearing timers, unsubscribing, and disconnecting external connections. React runs cleanup before the Effect is re-run because dependencies changed, and when the component is removed. Cleanup helps prevent duplicate subscriptions and resource leaks.

How would you explain the difference between rendering and an Effect?

Rendering should be a calculation of the UI from the component's current inputs. An Effect is for synchronizing that result or related state with an external system. If a calculation does not require an external system, it generally belongs in rendering. This separation keeps components easier to reason about and avoids unnecessary state updates.