These are questions we actually use to separate React developers who have shipped production apps from those who have only followed tutorials. For each one you get what a strong answer covers and the red flag that tells you to keep digging — so a non-React interviewer can still run a rigorous screen.
Hiring a React developer is easy. Telling a real one from a convincing résumé is the hard part — and it’s most of what we do. The questions below are grouped by level, because the same question that stretches a junior is a warm-up for a senior.
Junior React interview questions
0–2 years
Fundamentals and whether they understand what React is doing under the hood.
What is the difference between state and props?
Props are read-only inputs passed from a parent; state is local, mutable data owned by the component and updated via useState/setState, which triggers a re-render. A strong answer notes that you never mutate props, and that lifting state up is how sibling components share it.
Says you can “change props from inside the component,” or mutates state directly (state.x = 1) instead of using the setter.
Why does React need a key when rendering a list?
Keys give elements a stable identity so React’s reconciler can match items between renders and avoid re-creating DOM unnecessarily. A good candidate explains why the key must be stable and unique, and why the array index is a bug when the list can reorder, filter, or have items inserted.
Reaches for the array index by default with no caveat, or thinks keys are “just to remove a console warning.”
What is the virtual DOM, and what problem does it solve?
An in-memory tree React diffs against the previous render to compute the minimal set of real DOM mutations (reconciliation). The insight to listen for: the virtual DOM isn’t magically fast — it’s a batching/diffing strategy that trades some memory and CPU for fewer, cheaper DOM writes.
Claims the virtual DOM “is faster than the DOM” as a slogan with no notion of diffing or reconciliation.
Mid-level React interview questions
2–5 years
Whether they can reason about the render lifecycle and write hooks that don’t leak or go stale.
What are the common pitfalls with useEffect?
Missing or wrong dependencies causing stale closures; forgetting the cleanup function for subscriptions, timers, or event listeners; and running effects that should have been derived state or an event handler instead. A strong answer treats the dependency array as a correctness tool, not a performance knob.
Routinely disables the exhaustive-deps lint rule to “make the warning go away,” or puts logic in an effect that belongs in an event handler.
When would you reach for useMemo, useCallback, or React.memo — and when not?
When a genuinely expensive computation or a referentially-stable prop is causing measurable re-render cost, ideally confirmed with the Profiler. The senior instinct is that memoization has its own cost and complexity, so you measure first and memoize the hot path, not everything.
Wraps every value and callback in useMemo/useCallback reflexively, believing it is always faster.
How do you prevent unnecessary re-renders in a large component tree?
Split components so state lives as low as possible; lift only what needs sharing; use React.memo on pure leaf components; keep context values stable or split contexts; and move high-frequency state out of context. Bonus for mentioning measuring with the React DevTools Profiler before optimizing.
Immediately proposes a global store as the fix, or can’t name a way to actually observe re-renders.
Senior React interview questions
5+ years
Architecture, tradeoffs, and how they debug problems they can’t reproduce locally.
How do you structure state in a large React application?
Separate server state (data from an API — cache, invalidate, and sync it with a tool like React Query or RTK Query) from client/UI state (local component state or a light store). A strong answer warns against putting server data in a global store by hand, and against using Context for high-frequency updates.
Puts everything — server data, form state, UI toggles — into one global Redux store, or uses a single Context for fast-changing values.
What do Server Components and streaming SSR change about how you build?
RSC let you keep data-fetching and heavy dependencies on the server, shipping less JS to the client, while client components handle interactivity; streaming/Suspense lets the page render progressively. A good candidate can articulate the tradeoffs (the client/server boundary, serialization, when CSR is still the right call).
No awareness of the client/server component split, or assumes it is a drop-in speed-up with no tradeoffs.
A page is janky in production but fine on your machine. How do you find the cause?
Reproduce with production-like data volume and CPU/network throttling; profile with the React Profiler and browser performance panel; look for excessive re-renders, large lists without virtualization, layout thrash, or unmemoized context. They instrument and measure before changing code.
Starts sprinkling useMemo everywhere without measuring, or blames the framework before profiling.
Want the other side of this? See how we run the whole assessment in our engineering onboarding playbook.