Home / Articles / React interview guide: hooks, rendering, and what large companies ask

This article is published in English.

React interview guide: hooks, rendering, and what large companies ask

Virtual DOM, hooks pitfalls, performance, state management, React 18, live coding exercises, and how to explain the why behind re-renders.

1332 words

Large-company React interviews rarely grade you on doc recitation. They grade whether you know what happens underneath—why a component re-renders, why an effect fires twice, why a state update did not show up immediately. Candidates who can explain why beat candidates who only know how.

Below is how the usual topics actually appear: fundamentals, hooks, performance, patterns, and the curveballs that show up everywhere.

1. Core fundamentals

Warm-up questions almost always cover:

  • Virtual DOM — what it is and why updates feel faster (diff/reconcile instead of raw DOM writes).
  • Reconciliation — how React chooses what to update (keys, element type checks).
  • JSX — sugar that compiles to React.createElement(); know that cold.
  • Controlled vs uncontrolled — controlled inputs follow React state (value + onChange); uncontrolled ones read the DOM through refs.
  • Props vs state — props are read-only from above; state is local and changed via setters/hooks.
  • List keys — index-as-key breaks when order changes (wrong DOM/state reuse).

Trick question: “Why not use the array index as a key?” Answer with a concrete reorder/insert example where React attaches state to the wrong row.

2. Hooks (the densest interview section)

useState

  • Updates are async/batched.
  • Stale closures: several setCount(count + 1) calls in one event share the same count; setCount(prev => prev + 1) fixes it.

useEffect

  • Deps: [] once, omitted every render, listed deps only when those change.
  • Cleanup timing and purpose (leaks, cancel subscriptions/fetches).
  • Why effects run twice in development — React 18 Strict Mode double-invokes to expose missing cleanup. Nearly everyone hits this once.

useMemo vs useCallback

  • useMemo caches a value; useCallback caches a function identity.
  • Both protect referential equality for React.memo children or dependency arrays.
  • Overuse has a cost; interviewers like hearing that memoization is not free.

useRef

  • Mutable value across renders without re-render.
  • DOM nodes, previous values, timer IDs.

useContext

  • Ends prop drilling for a subtree.
  • Gotcha: a context update re-renders every consumer in the subtree, including ones that read just one field.

useReducer

  • Prefer when logic is complex or several fields update together (local Redux-shaped reducers).

Custom hooks

  • Be ready to write useDebounce, useFetch, or useLocalStorage live—one of the most common practical exercises.

3. Rendering and performance

Mid/senior rounds separate people here.

  • Why re-render? parent re-render, state change, context change, or props that look equal but are new references.
  • React.memo — shallow prop compare; useless if you pass fresh objects/functions each time (pair with useMemo/useCallback).
  • Code splitting — React.lazy + Suspense.
  • Windowing — react-window-style virtualization for huge lists.
  • Fewer re-renders — push state down, split contexts, memoize deliberately.
  • Profiler — measure instead of guess.

Classic prompt: 10,000-row list lags while typing in search. Expect debounce, virtualization, and memoized rows.

4. State management

  • Local vs global vs server state — naming server state (cache, revalidate, loading/error) separately from UI state impresses panels.
  • Context vs Redux/Zustand — Context for rare globals (theme, auth); Redux/Zustand when you want middleware, tools, complex updates, or frequent writes without context thrash.
  • React Query / SWR / TanStack Query — caching, background refetch, dedupe so you stop reinventing useEffect fetch glue.
  • Redux basics (if the stack uses it): actions, reducers, store, thunk/saga middleware, pure reducers.

5. Design patterns

  • HOCs — wrap a component; classic withAuth.
  • Render props — share logic via a function prop; mostly replaced by hooks but still asked conceptually.
  • Compound components — siblings sharing implicit state via context (Select / Select.Option).
  • Container/presentational — data vs UI; less rigid with hooks, but separation of concerns still matters.
  • Composition over inheritance — React’s preferred reuse story; be ready to justify it.

6. Class lifecycle (still asked)

Hooks-first shops still probe foundations or legacy codebases.

  • componentDidMount ≈ useEffect(() => {}, [])
  • componentDidUpdate ≈ effect with deps
  • componentWillUnmount ≈ effect cleanup
  • Error boundaries — class-only (componentDidCatch / getDerivedStateFromError); hooks lack a peer, which is why wrappers like react-error-boundary exist.

7. React 18+ awareness

  • Concurrent rendering — interruptible work for a more responsive UI.
  • useTransition — mark non-urgent updates so typing stays snappy.
  • useDeferredValue — delay non-critical UI.
  • Automatic batching — batches inside promises, timeouts, and native handlers (not only React handlers).
  • Suspense for data — more relevant with Next.js/Remix-style stacks.
  • Server Components — what runs where, and why client bundles shrink.

8. JavaScript that sneaks in

  • Closures — stale hook state.
  • Event loop / micro vs macro tasks — why batching feels the way it does.
  • this binding — if classes appear.
  • Debounce vs throttle — almost guaranteed, often as “optimize this search box.”
  • Shallow vs deep compare — React.memo / useMemo and why object literals kill memoization.
  • Promises / async-await — fetch races when users type fast.

9. Testing

  • Testing Library — behavior over internals (role/text queries).
  • Jest — mock APIs; know snapshot limits.
  • Unit vs integration vs e2e, and where component tests usually sit.

10. Live coding that repeats

  • Debounced search/autocomplete
  • Custom useFetch with loading/error/data
  • Infinite scroll or pagination
  • Modal via portal (createPortal) and why portals exist (escape overflow/z-index while staying in the React tree for events/context)
  • Counter with undo/redo via useReducer
  • “Spot the bug” on stale closures or missing deps

Sample walkthrough

“Why did this useEffect infinite-loop?”

useEffect(() => {
  setData({ ...data, updated: true });
}, [data]);

Strong answer: the effect lists data as a dependency, then writes a new object back into data, so each run changes the dependency and retriggers immediately. Fix by dropping data from deps when it should not retrigger, moving the update out of the effect, or using a functional updater with a tighter dependency.

Explaining why it breaks—not only proposing a patch—is what separates strong React interview answers.

Closing

Depth beats memorized API surface area. Interviewers want rendering behavior, closures, and performance trade-offs—the bugs that show up in production. Prep by building tiny components that break on purpose (stale closures, missing deps, wasteful re-renders) and fixing them. That debugging instinct is what the interview is really scoring.

When you practice, time-box yourself the way interviews do: explain Virtual DOM in sixty seconds, then debug a stale-closure snippet, then sketch a debounced search. That rotation matches how panels actually move.

How panels usually escalate

Warm-ups stay in Virtual DOM, controlled inputs, and keys. Mid rounds move to hooks: batched updates, Strict Mode double effects, memo versus callback, and writing a custom hook live. Senior rounds live in performance stories—ten-thousand-row lists, context thrash, Profiler evidence—and architecture choices between Context, Redux/Zustand, and TanStack Query for server state.

Keep a personal “broken on purpose” repo: a stale-closure counter, a missing-deps effect, a memoized list that still re-renders because of inline objects, and a portal modal. Explaining those four fixes aloud covers a surprising fraction of live coding and whiteboard time.

If the role mentions React 18+, be ready with one sentence each on concurrent rendering, transitions, deferred values, automatic batching, and Server Components. Depth on one shipping story beats vague awareness of every RFC.