Skip to content
Intermediate10 min study

React effects

Synchronize with external systems without creating fragile data flow.

Question progress0 / 10 completed
Start the lesson
React effects visual explanation

WHAT YOU WILL BE ABLE TO DO

Learning outcomes

  • Explain react effects in plain language.
  • Connect the behavior to the underlying browser or framework model.
  • Implement the core pattern and reason through edge cases.
  • Answer common follow-ups without relying on memorized phrases.

01Synchronization

An Effect synchronizes a component with something outside React — a subscription, a DOM API, a timer, a network connection. It is not a general-purpose “run this after render” hook, and most Effects that compute derived UI state can be replaced by calculating that value directly during render.

02Dependencies

The dependency array tells React which reactive values the synchronization logic reads. When any of them changes, React re-runs the Effect so the external system stays in sync with the latest props and state.

JavaScript
useEffect(() => {  const controller = new AbortController();  fetch(`/api/users/${userId}`, { signal: controller.signal })    .then((res) => res.json())    .then(setUser);  return () => controller.abort();}, [userId]);

03Cleanup

  • The cleanup function runs before the next Effect execution and on unmount — it should undo exactly what the Effect set up (unsubscribe, abort, clear).
  • Missing dependencies cause stale closures over old props/state, not just lint warnings.
  • Effects that only compute a value from props/state belong in render, not in an Effect plus extra state.

DDConcept deep dives

Deep dive 1

Effects synchronize with systems outside React

Rendering describes UI from current props and state. An effect is needed when that rendered presence must establish or update an external relationship: a network connection, event subscription, timer, browser API, analytics impression, or imperative library. If a value can be calculated from existing render inputs, calculating it directly avoids an extra stale render and synchronization loop.

  • User-caused actions normally belong in the event handler that knows what happened.
  • External synchronization belongs in an effect tied to the values that describe it.
  • Data fetching may be better owned by the framework or a cache with deduplication and server support.

Deep dive 2

Dependencies describe reactive reads

Props, state, and values created in the component participate in the render snapshot. If an effect reads them, its dependency list must represent them so synchronization updates when those values change. Suppressing the lint warning creates a mismatch between code and declared dependencies; restructure the effect or move nonreactive logic rather than lying to React.

  • Updater functions can remove a dependency when only the previous state is needed.
  • Objects created during render change identity unless moved, memoized, or created inside the effect.
  • Separate unrelated synchronization processes into separate effects.

Deep dive 3

Cleanup makes setup reversible

Before an effect resynchronizes, React invokes the prior cleanup, and it also cleans up on unmount. Development Strict Mode deliberately probes setup-cleanup-setup behavior to reveal resources that cannot be safely reacquired. A correct effect should be observationally equivalent whether setup happens once or is cleaned and established again.

  • Unsubscribe with the exact subscription identity you created.
  • Abort or invalidate obsolete asynchronous work.
  • Clear timers and disconnect observers owned by the component.
TSX
useEffect(() => {  const controller = new AbortController();  loadUser(userId, controller.signal).then(setUser).catch((error) => {    if (error.name !== 'AbortError') setError(error);  });  return () => controller.abort();}, [userId]);

Changing userId aborts the request owned by the previous effect before the new synchronization begins.

QAInterview questions and model answers

Attempt each answer aloud before opening it. The model answer shows the depth and precision expected in an interview; it is not a script to memorize.

Intermediate · Coding · 1 min · Question 1What is useEffect for?Open model answer

Model answer

An effect synchronizes a rendered component with an external system such as a subscription, network connection, timer, imperative widget, or browser API. It is not the default place for values that can be derived during render or logic caused directly by an event.

JSX
useEffect(() => {  const conn = createConnection(roomId);  conn.connect();  return () => conn.disconnect(); // undo exactly what was set up}, [roomId]);
Open question page →
Intermediate · Conceptual · 1 min · Question 2How should the dependency list be chosen?Open model answer

Model answer

It must include every reactive value read by the effect. The list describes the code's dependencies; it is not a manual scheduling preference. If that causes excessive reruns, restructure ownership, stabilize a value where semantically appropriate, or remove an unnecessary effect.

Open question page →
Intermediate · Conceptual · 1 min · Question 3When does cleanup run?Open model answer

Model answer

Cleanup runs before an effect is set up again with changed dependencies and when the component unmounts. In development Strict Mode, React may run an extra setup-cleanup cycle to reveal missing cleanup and non-idempotent synchronization.

Open question page →
Advanced · Coding · 1 min · Question 4How do you prevent stale network responses from winning?Open model answer

Model answer

Abort the obsolete request when possible and guard state commits with request identity or an ignore flag scoped to the effect. Cleanup marks the old synchronization as obsolete. Debouncing alone does not solve response races.

JSX
useEffect(() => {  let ignore = false;  fetch(`/api/users/${userId}`)    .then((r) => r.json())    .then((data) => { if (!ignore) setUser(data); });  return () => { ignore = true; }; // last effect to run wins}, [userId]);
Open question page →
Intermediate · Coding · 1 min · Question 5What is the difference between useEffect and useLayoutEffect?Open model answer

Model answer

useEffect generally runs after the browser paints, while useLayoutEffect runs after DOM commit but before paint and can block it. Layout effects are for synchronous measurement or mutation that must be visually atomic; ordinary synchronization should use useEffect.

JSX
useLayoutEffect(() => {  const { height } = ref.current.getBoundingClientRect();  setTooltipTop(-height); // measured + applied before the user sees a flash}, [content]);
Open question page →
Intermediate · Coding · 1 min · Question 6Why is copying props into state with an effect often wrong?Open model answer

Model answer

It creates two sources of truth and an extra render with temporarily stale derived state. Compute inexpensive values during render, memoize only costly pure computation when measured, or deliberately reset state through identity when the product requires it.

JSX
// Anti-pattern: effect mirrors a prop into stateuseEffect(() => setFullName(`${first} ${last}`), [first, last]);
// Just derive during render:const fullName = `${first} ${last}`;
Open question page →
Advanced · Conceptual · 1 min · Question 7What is an effect event conceptually?Open model answer

Model answer

It separates nonreactive event-like logic from an effect's reactive synchronization, allowing code to read current values without falsely making them synchronization dependencies.

Open question page →
Advanced · Conceptual · 1 min · Question 8Should an effect set state from props on every change?Open model answer

Model answer

Usually no, because it duplicates derivable data and causes an extra render. Deliberate state reset should use identity or an explicit product transition.

Open question page →
Advanced · Conceptual · 1 min · Question 9Why can an effect loop forever?Open model answer

Model answer

It sets state, that update changes one of its dependencies—often a freshly created object—and the effect runs again. Fix the ownership or unstable dependency.

Open question page →
Beginner · Conceptual · 1 min · Question 10Do effects run during server rendering?Open model answer

Model answer

No. Effects are client-side synchronization after commit. Server output must not depend on an effect having run.

Open question page →

SCScenario questions

Scenario 1

A profile flashes the previous user's data after rapidly switching accounts.

  1. Tie each request to the user id that created it.
  2. Abort the previous request in effect cleanup.
  3. Prevent obsolete completion from committing state.
  4. Represent loading and empty states without preserving misleading data.
Reveal worked answer

The effect should synchronize with the current user id. Its cleanup aborts the prior fetch, and the completion checks that it still belongs to the active request before setting state. I would decide whether to clear previous data immediately or show it as explicitly stale, rather than accidentally presenting it as the new profile.

Verify and go deeper