React Interview Questions & Answers (2026)

React interviews in 2026 test three axes: the hooks model (rules, useEffect footguns, useMemo/useCallback discipline), the reconciliation algorithm (keys, virtualization, why children re-render), and Server Components (RSC boundaries, streaming, hydration). This guide covers 15 questions we've seen candidates hit at Meta, Vercel, Stripe, Shopify, and Airbnb frontend interviews in the last 12 months.

✍️ John Nap, Product Reviewer, MiPrep Published Jul 27, 2026 Updated Jul 27, 2026 13 min read 🔒 Private-by-default
Why it matters: React powers most consumer web frontends and every meaningful startup's product surface. Meta invented it and interviews for it. Vercel, Shopify, Stripe, Airbnb, and Netflix all run React-heavy loops. If your interview panel includes a frontend or full-stack round, you will be asked at least one hooks question and at least one performance question. Getting Server Components right in 2026 is the differentiator between mid and senior.

Beginner questions

1. Explain the Rules of Hooks. Beginner

MetaVercel

Two rules. (1) Only call hooks at the top level — never inside conditions, loops, or nested functions. (2) Only call hooks from React function components or other hooks. React tracks hook state by call order across renders; conditional calls break the ordering and the wrong state ends up at the wrong hook. The ESLint plugin catches most violations at build time.

2. What is the virtual DOM and why does it matter? Beginner

MetaShopify

A tree of JavaScript objects describing the desired UI. On each render React builds a new virtual DOM, diffs against the previous one, and applies the minimal set of real DOM mutations. This exists because direct DOM mutation is slow and imperative; declarative render + diff scales. In 2026 the term is being replaced by 'React elements + reconciler.'

3. Why do you need a 'key' prop in a list? Beginner

MetaShopify

The reconciler uses keys to match up children between renders. Without a stable key, React defaults to positional matching — when you insert an item at the front, every child gets 'moved down' and re-created, losing local state. Use a stable ID from data (post.id), NEVER the array index — that produces the exact bug the key was supposed to prevent.

4. What is a controlled vs uncontrolled component? Beginner

ShopifyStripe

Controlled: React state owns the value, onChange writes back. <input value={x} onChange={e => setX(e.target.value)}. Uncontrolled: DOM owns the value, React reads via ref. Controlled is default — validation, formatting, and conditional disable all get easier. Uncontrolled wins for large forms where every keystroke re-render is a perf cost. react-hook-form uses uncontrolled internally for this reason.

Practice these live, in your voice

MiPrep's practice mode turns your resume into a rehearsed answer set. Talk through the idioms the way top-tier interviewers score.

Download MiPrep 🔒 Interview audio is never stored on our servers

Intermediate questions

5. Explain useEffect's dependency array. Intermediate

MetaVercelStripe

useEffect runs after render. The deps array controls re-execution: [] runs once after mount, [a, b] re-runs when a or b changes by Object.is comparison, no array re-runs on every render. Every value used inside the effect that isn't stable across renders must be in deps — the exhaustive-deps ESLint rule enforces this. Common bug: including a function created inline in the parent that changes identity every render, so the effect re-fires infinitely. Fix with useCallback in the parent or move the function into the effect.

6. What's the difference between useMemo and useCallback? Intermediate

Meta

useMemo(() => compute(a, b), [a, b]) caches a VALUE across renders. useCallback(fn, [a, b]) caches a FUNCTION. useCallback(fn, deps) is equivalent to useMemo(() => fn, deps). Both are optimization hints — do NOT reach for them by default. Use when: (1) the value is expensive to compute, (2) the function is passed to a memoized child and identity matters, (3) the value is in another hook's deps and would cause a loop.

7. Explain useState vs useReducer. Intermediate

Meta

Both hold local state. useState is fine for independent primitives. useReducer wins when: (1) multiple state fields change together in specific transitions, (2) the next state is a pure function of previous state and an action (testable in isolation), (3) you want to log every state transition. useReducer + useContext is a lightweight Redux replacement for medium apps.

8. How does React batch state updates? Intermediate

Meta

React 18+ batches all updates in the same microtask by default — including in setTimeout, Promise chains, and native event handlers. Previously batching only happened in React event handlers. Effect: multiple setState calls trigger a single re-render. flushSync(fn) forces immediate render when you need it (rare — usually for third-party code that needs DOM updated synchronously).

9. Explain Context and when to avoid it. Intermediate

MetaVercel

Context provides state to a subtree without prop-drilling. Every consumer re-renders when the provider value changes — even if they use a different field. Avoid for high-frequency updates (mouse position, animation state); use a state library (Zustand, Jotai) or subscribe pattern. Context is right for: theme, user, i18n, feature flags — things that change rarely.

10. What's new in React 19? Intermediate

MetaVercel

Actions (form actions with automatic pending state via useFormStatus and useActionState). Improved Suspense (sibling suspense boundaries no longer block each other). use() hook (unwraps a promise or context directly in render, works with Suspense). Better hydration error messages. Ref as a prop (no more forwardRef for most cases). React Compiler in RC — auto-memoization at build time, ends the useMemo/useCallback discipline for well-behaved code.

Advanced questions

11. What are Server Components? Advanced

VercelMeta

Server Components render on the server and stream serialized output to the client. They can be async, access databases directly, and have zero JS in the bundle. Client Components (marked with 'use client') hydrate on the client and have interactivity (useState, event handlers). The boundary matters: props flowing from RSC to Client must be serializable. In Next.js App Router, pages default to server; the whole tree becomes a client tree at the first 'use client' import.

12. What is Suspense? Advanced

VercelMeta

Suspense is React's declarative loading state. Wrap a child that reads from a data source; if the data isn't ready, the child throws a promise; Suspense catches it and renders the fallback. With RSC + Next.js, Suspense enables streaming — the server flushes fallback HTML immediately and streams the resolved content later. Client-side, Suspense + startTransition + useDeferredValue is the model for non-blocking updates.

13. How would you debug a slow React app? Advanced

MetaVercel

Start with the React DevTools Profiler — record an interaction, look at flame graph, identify the components taking the longest and re-rendering unnecessarily. Common fixes: memo() around expensive pure children, useMemo the expensive derived value, virtualize long lists with react-virtual or react-window, code-split with React.lazy for the largest chunks, move state down so unrelated components don't re-render. If it's a render-blocking effect, move it to useLayoutEffect or defer with useDeferredValue.

14. What is hydration? Advanced

VercelMeta

The server renders HTML; the client downloads JS and attaches event handlers to that existing HTML. Hydration mismatch = server-rendered HTML differs from what the client renders on first pass — logs a warning and can break. Common causes: rendering Date.now() in a component, Math.random() at render, or a client-only value that isn't marked useEffect. React 19 introduced better recovery paths, but avoiding the mismatch is still cheaper than fixing it.

15. Design a autocomplete component. Advanced

MetaStripe

State: query, results, activeIndex, loading. Debounce query (150-300ms), cancel in-flight fetches with AbortController when a new query fires. Show a listbox with role='listbox' and role='option', wire keyboard nav (ArrowUp/Down, Enter, Escape). Track loading, error, and empty separately. If the API returns quickly, hide the spinner to avoid UI flicker. Discuss race conditions: the second-most-recent response arriving after the most-recent — protect with a sequence number.

Common mistakes candidates make

  • Depending on state values in useEffect deps without including them — stale closures.
  • Using array index as key — breaks when the list mutates order.
  • Wrapping every function in useCallback — makes the code worse, not faster.
  • Reading state immediately after setState and expecting the new value — you get the old value until re-render.
  • Mixing Server Components with 'use client' components incorrectly — client boundary spreads further than intended, ships more JS.

Study strategy

Two-week plan. Week 1: build 3 small apps that stress hooks (autocomplete, drag-and-drop, chat) — each one uncovers a hook footgun. Week 2: read the React 19 docs section on Actions + use() and rebuild one of your apps with them. Practice explaining reconciliation aloud — most candidates can code React but can't explain why re-renders happen when they do.

Do timed mocks with MiPrep before the real thing

Upload your resume and target job description. MiPrep generates a rehearsed answer set in your voice from your own projects — so mock interviews sound like real ones.

Get MiPrep — free 🔒 Interview audio is never stored on our servers