Advanced React Interview Questions
12 React interview questions for senior and lead developers (5+ years): Server Components, useActionState, useOptimistic, the React Compiler, hydration, transitions and virtualisation. Each answer explains why the other options are wrong.
CoversBundlingConcurrentFormsHydrationListsPerformanceReactReact 19React compilerServer componentsSsr
By Deepak KumarPublished Answers checked by Deepak
Take it as a timed test
- 12 questions
- 18 min
- Pass mark 60%
- Answers shown at the end
No sign-up. Your answers and scores stay in this browser.
This pro paper has 12 React questions for senior and lead developers with roughly 5+ years of experience. It covers Server Components, useActionState, useOptimistic, the React Compiler, hydration, transitions and virtualisation. Ten questions are on this page with full explanations; the timed test also includes two questions that aren't shown here, so practise for understanding rather than memory.
How should you use this paper?
Answer each practice question before opening its explanation, and say your reasoning out loud the way you would in an interview. Then take the timed test: 18 minutes, a pass mark of 60%, with answers shown at the end. Your report breaks your score down by topic and difficulty, and you can retry only the questions you missed.
Practice questions with answers
Try each one before opening the answer. The explanation covers why the other options are wrong. The timed test also uses 2 questions that aren't shown here, so practise for understanding, not memory.
What is true about React Server Components?
Show answer and explanation
Answer: A. They run only on the server, their code isn't sent to the browser, and they can't use state or effects
Server Components render on the server (at build time or per request). Their code and any large libraries they import stay off the client bundle, and they can read databases or files directly. Because they don't run in the browser, they can't use useState, effects or event handlers; those parts go in Client Components marked with 'use client'.
What does React 19's useActionState(action, initialState) return?
Show answer and explanation
Answer: A. [state, formAction, isPending]: the latest result, an action to pass to a form, and whether it's running
You give it an action function, which receives the previous state and the form data, plus an initial state. It returns the current state (such as validation errors or a success message), a wrapped action for <form action={formAction}>, and an isPending flag for disabling the button. It replaced the earlier useFormState name.
What is useOptimistic for?
Show answer and explanation
Answer: A. Showing the expected result immediately while an async action runs, then settling to the real result
With useOptimistic, a like or a new comment appears instantly, before the server confirms it. React shows the optimistic state while the action is pending and replaces it with the real state when the action finishes; if it fails, the optimistic value disappears. It makes apps feel fast without hand-written rollback code.
Which of these can a Server Component NOT do? Select all that apply.
Show answer and explanation
Answer: A. Use useState + B. Attach an onClick handler
Server Components can be async and await data from a database, file system or internal API right in the component, which is one of their main benefits. They can't hold state, run effects or attach browser event handlers, because their code never reaches the browser. Put interactive pieces in Client Components and pass server data to them as props.
Adding 'use client' at the top of a file puts that component, and the modules it imports, into the client bundle.
TrueFalse
Show answer and explanation
Answer: True
True. 'use client' marks a boundary: that module and everything it imports become client code. A common mistake is putting it on a high-level layout, which drags the whole subtree into the bundle. Keep the directive on small, interactive leaf components, and pass Server Components to them as children where needed.
What does the React Compiler do?
Show answer and explanation
Answer: A. Automatically memoises components and values at build time, so you need fewer manual useMemo and useCallback calls
The React Compiler analyses your components at build time and inserts memoisation where it's safe, so unchanged parts skip re-rendering without hand-written useMemo, useCallback or React.memo. It relies on your code following the rules of React, such as pure render functions and no state mutation; code that breaks them is skipped.
A server-rendered page logs a hydration mismatch warning. Which is a likely cause?
Show answer and explanation
Answer: A. Rendering Date.now(), Math.random() or browser-only values like window.innerWidth during render
Hydration expects the first client render to produce the same HTML as the server. Values that differ between the two (time, random numbers, locale-dependent formatting, or window checks during render) cause a mismatch. Render a stable value first and update it in useEffect, or pass the value from the server. Browser extensions that edit the DOM can also trigger it.
Typing in a search box feels laggy because filtering a big list re-renders on every keystroke. Which React feature helps most?
Show answer and explanation
Answer: A. useTransition or useDeferredValue, so the input updates first and the heavy list renders at lower priority
Concurrent rendering lets React interrupt non-urgent work. Wrap the filter update in startTransition, or render the list from useDeferredValue(query), and the input stays responsive while React prepares the list in the background, discarding stale renders. If the list is very long, combine this with virtualisation so only visible rows are rendered.
Match each React API to its job.
- use()
- useDeferredValue
- startTransition
- Suspense
- Show a stale value while a fresh one renders in the background
- Mark a state update as non-urgent
- Show a fallback while something inside is loading
- Read a promise or context during render
Show answer and explanation
Answer: use() → Read a promise or context during renderuseDeferredValue → Show a stale value while a fresh one renders in the backgroundstartTransition → Mark a state update as non-urgentSuspense → Show a fallback while something inside is loading
use can unwrap a promise (suspending until it resolves) or read context, and unlike other hooks it may be called inside conditions. useDeferredValue lags a value behind for expensive renders. startTransition marks updates as interruptible. Suspense is the boundary that shows a fallback while data or code is loading.
A table must show 10,000 rows and scrolling stutters. What is the standard fix?
Show answer and explanation
Answer: A. Virtualise the list so only the rows in view (plus a small buffer) are rendered
Ten thousand rows mean tens of thousands of DOM nodes, which is slow to lay out and scroll no matter how fast React renders. Virtualisation libraries such as react-window or TanStack Virtual render only what is visible and reuse rows as you scroll, keeping the DOM small. Pagination or infinite loading are alternatives when users don't need everything at once.
Answered them all? Take the same questions against the clock and get a topic-by-topic report.
Start the timed test