50% off all plans with SPRING50
React · 22 min read

React Interview Playbook 2026

The React-specific guide to frontend interviews. Hooks, rendering, state management, performance, and the coding challenges that come up in every React interview loop in 2026.

If you are interviewing for a React role in 2026, the bar has shifted. Knowing hooks is table stakes. What separates senior candidates is judgment: knowing when not to reach for a hook, when to lift state, when to colocate, when useMemo is premature optimization vs necessary, and how to reason about rendering behavior without a profiler.

This guide covers every React-specific question I have seen come up in frontend interviews at Big Tech, mid-market, and startups over the last two years.

What React interviews actually test

Three things, in order:

  1. Correct, idiomatic hook usage — not clever, not fancy. Clean state updates, stable dependencies, no effects where memoization would do, no memoization where state colocation would do.
  2. A mental model of rendering — why a component re-rendered, how you would diagnose it, what a key actually does, why your effect ran twice in dev.
  3. Practical trade-offs — when to use context vs props vs a store, when to split components, when to lift state, when to defer, when to suspend.

Deep React internals (fibers, lanes, scheduler priorities) rarely come up outside of Meta. Do not spend two weeks on that. Spend two weeks on the three things above.

Hooks in depth

Know each of these cold. If an interviewer asks “what does useCallback actually do,” you should be able to answer without hedging:

useState

  • State is set asynchronously — reads inside the same function see the old value.
  • Functional updates setX(x => x + 1) are the correct pattern for anything that depends on the previous value.
  • Lazy initializer: useState(() => expensive()) runs once.
  • Never mutate state in place. Always return a new object/array.

useEffect

  • Runs after paint, not before. If you read layout in it, you will see old layout.
  • Dependency array: if you lie about dependencies, the linter will catch you and the behavior will bite you.
  • Cleanup function runs before the next effect and on unmount.
  • In React 18+ Strict Mode, effects run twice in dev — by design. Your effect must be idempotent.

useLayoutEffect

  • Runs synchronously after DOM mutation, before paint.
  • Use it when you need to measure layout and update state in the same frame (e.g., tooltip positioning).
  • Avoid in server-rendered code — it throws a warning.

useRef

  • Mutable box that persists across renders and does not trigger re-renders.
  • Two uses: (1) DOM refs via JSX ref={}, (2) imperative values that should not cause re-renders (timers, counters, previous values).

useMemo and useCallback

  • Memoize values and functions respectively. Both take a deps array.
  • Do not sprinkle them everywhere. They have a cost. Use them when:
    • The computation is genuinely expensive (rare), OR
    • You are passing the value to a memoized child and want to keep props referentially stable.
  • 90% of useCallback uses in the wild are unnecessary.

useContext

  • Reads the nearest context provider. Every consumer re-renders when the context value changes.
  • Common mistake: putting frequently-changing state in a single context and wondering why the whole tree re-renders. Split contexts by update frequency.

useReducer

  • Preferred over useState when state updates are complex, interrelated, or need to be testable in isolation.
  • The reducer is a pure function — same input, same output. This is why it is easy to test.

useTransition and useDeferredValue

  • Mark state updates as non-urgent so React can interrupt them if a higher-priority update (like typing) comes in.
  • useTransition wraps a state update. useDeferredValue wraps a value passed down.
  • Use these when a filter/search operation is slow and you want the input to stay responsive.

useSyncExternalStore

  • The hook you reach for if you are building a custom store that needs to stay in sync with React’s concurrent rendering.
  • You will rarely write this yourself, but if an interviewer asks “how would you integrate a Redux-like store with concurrent React,” this is the answer.

Rendering and reconciliation

A component re-renders when:

  1. Its state changes (via a setter).
  2. Its parent re-renders and passes new props (even if the props are the same by value, the reference might be new).
  3. A context it consumes changes value.
  4. A hook it uses triggers a re-render (e.g., useSyncExternalStore).

Common questions:

  • “Why is this component re-rendering when I click a button in a sibling?” — Most likely because the shared parent re-renders and both children re-render along with it. Fix: memoize the child that shouldn’t care, or lift state down.
  • “Why does my effect run twice?” — Strict Mode. React 18+ intentionally runs effects twice in dev to surface cleanup bugs. Not a bug.
  • “What does key actually do?” — It tells React’s reconciler how to match children across renders. Without it, React matches by position. With it, React matches by identity. Using array index as a key is almost always wrong when the list can be reordered.

The fix for unnecessary re-renders is almost always one of: (1) memoize, (2) lift state down, (3) split context, (4) split component. In that order of difficulty.

State management decisions

One of the most common open-ended questions: “Where should this state live?”

Walk through these in order:

  1. Local component state — if only one component needs it. Default answer.
  2. Lifted state — if a small number of siblings need it. Lift to common parent.
  3. Context — if many components need it and it changes infrequently (theme, auth, locale).
  4. External store (Zustand, Jotai, Redux) — if many components need it and it changes frequently, or if you need devtools, time-travel debugging, or middleware.
  5. Server state library (React Query, SWR) — if the state is owned by a server and you need caching, refetching, and sync. Do not hand-roll this.
  6. URL state — if the state should survive navigation, sharing, and browser history. Search params or path segments.

The interviewer wants to hear you reason through this ladder, not memorize the “correct” answer. Correct is always “it depends.”

Performance patterns

Three buckets:

Rendering performance

  • React.memo — skip re-rendering a component if its props haven’t changed shallowly.
  • useMemo / useCallback — stabilize values/references passed to memoized children.
  • Virtualization — render only visible items in long lists (react-window, @tanstack/react-virtual).
  • Code splitting — lazy() + Suspense to defer loading a component until needed.

Network performance

  • Data fetching libraries with caching (React Query, SWR).
  • Request deduplication.
  • Pagination or infinite scroll instead of loading everything.
  • Optimistic updates for perceived speed.

Bundle performance

  • Tree shaking — avoid barrel imports that pull in whole modules.
  • Dynamic imports for route-level splitting.
  • Defer third-party scripts (analytics, ads) until after interaction.
  • Image optimization — modern formats, responsive sizes, lazy loading.

The interview question is often “the page feels slow — what do you investigate?” Your answer should walk through these three buckets in that order, asking clarifying questions about what “slow” means (initial load? interaction? scrolling?).

Common coding challenges

React-specific takehomes and live coding tasks cluster around these patterns. Build the matching BigDevSoon project to drill each one — every project ships with a Figma design and Merlin AI for hints.

Project drills (build these in React):

  1. Todo App — the universal opener. Add/delete/toggle/filter, localStorage persistence
  2. Quiz App — state machines, derived state, scoring, conditional rendering
  3. Just Weather — debounced API search, loading + error states, race conditions
  4. Pokedex — pagination, infinite scroll, filtering, React Query patterns
  5. Calculator — operator precedence, keyboard handling, edge cases
  6. Notely — global state with context or Zustand, multi-page routing
  7. Tic Tac Toe — immutable updates, win-condition derived state
  8. Blog — multi-page React Router, dynamic routes, forms with validation
  9. Find Movies — full-stack: REST API + auth + favorites
  10. FoodieGo — flagship full-stack: cart, checkout, optimistic updates

Daily UI challenges (component-level reps):

Drill each until you can build it in under 30 minutes.

Server components & RSC

In 2026, React Server Components are mainstream in Next.js shops. Know:

  • “Server” and “Client” components — the directive "use client" marks the boundary. Server components run on the server, never ship to the browser, and can await data directly.
  • Why they exist — smaller client bundles, direct DB access, better streaming.
  • What you cannot do in a server component — use hooks, handle events, use browser APIs.
  • Hydration — the server renders HTML, the client “hydrates” with interactive code. Mismatch = crash.

If the company uses Next.js or Remix, expect a few RSC questions. If not, know the concepts at a high level and move on.

Testing questions

Common asks:

  • “How do you test a React component?” — React Testing Library (RTL), not Enzyme. Test behavior, not implementation. Query by role, not by class name.
  • “How do you test a hook?”renderHook from RTL.
  • “How do you mock an API call?” — MSW (Mock Service Worker) is the 2026 answer. It intercepts network requests at the service worker level.
  • “What do you unit test vs integration test?” — Unit: pure logic (reducers, utils). Integration: component + effect + mocked API.

Trap questions

These come up often and trip people up:

“Why is useEffect running twice in dev?” — Strict Mode. On purpose. Your effect must be idempotent.

“Why does console.log(state) right after setState show the old value?” — State updates are asynchronous and batched. The state variable in the current function scope is the old one.

“What’s the difference between controlled and uncontrolled inputs?” — Controlled: React state is the source of truth (value + onChange). Uncontrolled: the DOM is the source of truth (defaultValue, read via ref). Default to controlled unless there’s a specific reason.

“Why does putting functions in useEffect deps cause infinite loops?” — Functions declared inside the component are new references every render. Wrap with useCallback or move outside the component.

“What does the key prop do on a list item?” — Tells React how to match items across renders. Using index is usually wrong.

“Why is my setInterval inside useEffect misbehaving?” — Closure over stale state. Either use a functional updater or store the callback in a ref.

Drill schedule

Two weeks out:

  • Day 1–3: Drill hooks. Rewrite useState + useEffect from memory. Build a small counter, todo, and debounced input without looking anything up.
  • Day 4–6: Drill rendering. Build a list with React.memo + useCallback and profile it in DevTools. Verify your assumptions.
  • Day 7–9: Drill the top 5 coding challenges from the list above.
  • Day 10–12: Drill system design. Pick an app (Slack, Twitter, Figma) and design the frontend out loud, 45 minutes each.
  • Day 13: Full mock interview with a friend. Behavioral + coding round back-to-back.
  • Day 14: Rest. Review your notes. Go to bed early.

Next steps: This guide is the React-specific deep dive. If you haven’t read the broader Frontend Interview Playbook yet, start there — it covers HTML, CSS, system design, and behavioral rounds that are relevant regardless of framework. Then come back here for the React reps.

For live coding practice, head to BigDevSoon Projects, Challenges, and Problems. Every coding challenge mentioned above is available with test cases and Merlin AI for hints.

If you have a structured timeline:

Put it into practice

Build real projects with Merlin AI and a live code editor. 7-day free trial.

Start 7-Day Free Trial