useEffect Hook — React Technical Interview Questions & Answers

useEffect Hook

useEffect Hook

  • useEffect runs after the browser paints. That is where fetch, subscriptions, document.title, and timers belong — not in the middle of render. If you fetch during render, you can start a request on every paint and freeze the tab. Effect means: after this UI is on screen, do this extra work.
  • The dependency array lists values the effect reads. [] → run after first paint, cleanup on unmount (≈ componentDidMount + willUnmount). [userId] → run again when userId changes. Omit the array entirely → run after every paint. If that effect calls setState, you can get an infinite loop. That is the exam trap.
  • Return a cleanup function. Timers: clearInterval. Listeners: removeEventListener. Fetch: abort or a dead flag so a late response does not setState on an unmounted screen. Forget cleanup, leave the page, ghost timers keep firing. Strict Mode in development may run mount → cleanup → mount on purpose to catch this. Don’t ‘fix’ it by removing Strict Mode. Fix the effect.
  • Let’s do a clock on the board. useState(0) for seconds. useEffect(() => { const id = setInterval(() => setT(x => x + 1), 1000); return () => clearInterval(id); }, []); Screen: 0s, 1s, 2s. Leave the page → interval dies. That story is lifecycle in hooks language.
  • Fetching: useEffect(() => { let dead = false; fetch('/api/user/' + id).then(r => r.json()).then(d => { if (!dead) setUser(d); }); return () => { dead = true; }; }, [id]); When id changes, cleanup ignores the old request, new request starts. Without that, user A’s slow response can overwrite user B.
  • Trap: missing deps (eslint exhaustive-deps is your friend). Trap: putting objects/arrays inline in deps so the effect runs every render. Trap: using useEffect to copy props into state for no reason — usually you should just render the prop. Trap: thinking useEffect runs before paint (that is closer to useLayoutEffect, a rarer tool).
  • useEffect Hook — mount fetches count. Leave page → dead flag ignores late JSON. [] means once.
render
      │ paint
      ▼
  useEffect
      │ unmount / deps change
      ▼
    cleanup()

Technical Interview Tip: After paint + deps + cleanup. Mention Strict Mode double invoke.

Code Examples for useEffect Hook

Example

// useEffect fetch
import { useEffect, useState } from "react";

export default function Users() {
  const [n, setN] = useState(0);
  useEffect(() => {
    let dead = false;
    fetch("/api/count")
      .then((r) => r.json())
      .then((d) => { if (!dead) setN(d.n); });
    return () => { dead = true; };
  }, []);
  return <p>{n} users</p>;
}

useEffect Hook — mount fetches count. Leave page → dead flag ignores late JSON. [] means once.

How to Explain useEffect Hook to an Interviewer

When does useEffect run?

After paint

What does [] mean?

Once on mount Cleanup on unmount

Why cleanup a fetch?

Ignore late responses