The short answer: React interviews test whether you understand how React renders (state changes trigger a render, React calls your components, then commits only what changed to the DOM), the Rules of Hooks, when an Effect is the wrong tool, keys and component identity, and what changed in React 19: Actions, useActionState, use, ref as a prop and Server Components. Senior rounds add debugging scenarios (“why does this Effect run twice?”, “why did this input lose its value?”) and design questions. Every answer below is checked against react.dev, the official documentation, and the dated versions are listed at the end.
What React interviews look like in 2026
Most front-end loops mix four formats:
- Concept questions: explain rendering, hooks, state, keys, effects and performance in your own words, with a small example.
- Live coding: build a component in a shared editor or sandbox, such as a search box with a debounced fetch, a todo list, tabs, an accordion or a modal.
- Debugging and scenarios: you’re shown a bug (stale data, a state reset, an Effect that loops) and asked to explain and fix it.
- Behavioral and design: how you’ve handled performance, accessibility, code review, or a disagreement with a designer, and for senior roles how you’d structure a larger front-end.
Know which React you’re being asked about. The current line is React 19 (stable since December 5, 2024), with 19.2 (October 1, 2025) and 19.3 (September 9, 2026). The React Compiler reached its first stable release, 1.0, on October 7, 2025, and the React team deprecated Create React App for new apps on February 14, 2025.
Rendering and component questions
“What is React, and what problem does it solve?”
React is a library for building user interfaces out of components: functions that take props and return what should appear on screen. You describe the UI for a given state, and React updates the page when that state changes, so you don’t write DOM updates by hand.
“Explain the virtual DOM.”
It’s still one of the most common questions, but react.dev doesn’t use the term. It describes three steps instead:
- Trigger: a render starts on the initial render (
createRoot(...).render(...)) or when state is updated: calling asetfunction “automatically queues a render.” - Render: “Rendering is React calling your components” to work out what should be on screen.
- Commit: React then modifies the DOM, and it “only changes the DOM nodes if there’s a difference between renders.”
A strong answer uses that vocabulary, then adds: rendering is meant to be pure (same inputs, same JSX, no side effects), which is why React can call components more than once.
“What is JSX?”
A syntax extension that lets you write markup inside JavaScript. It compiles to function calls that create React elements, so it can contain any JavaScript expression in curly braces, and attributes follow JavaScript naming (className, onClick).
“What’s the difference between props and state?”
Props are inputs passed from a parent, read-only inside the component. State is memory the component owns and updates with its set function, which queues a re-render. If two components need the same changing value, lift the state up to their closest common parent and pass it down as props.
“Controlled vs uncontrolled inputs?”
A controlled input gets its value from state and reports changes through onChange, so React is the single source of truth. An uncontrolled input keeps its own value in the DOM, and you read it when needed (on submit, or through a ref). Controlled inputs make validation and conditional UI easier; uncontrolled ones are simpler for plain forms.
“Why does React need keys in lists?”
“Keys tell React which array item each component corresponds to,” so it can match items correctly when they’re inserted, removed or reordered. Use stable IDs from your data (database IDs, or crypto.randomUUID() when you create an item). The docs warn that an index “often leads to subtle and confusing bugs” when the order changes, and that key={Math.random()} means keys never match between renders, so everything is recreated. Keys only need to be unique among siblings, and they aren’t passed as a prop.
“Why did my component’s state reset (or not reset)?”
State is tied to a component’s position in the UI tree, not to the JSX tag. The same component type at the same position keeps its state across renders; a different type at that position destroys it, along with the whole subtree. To reset state on purpose, render the components at different positions or give them a different key. A classic bug: defining a component inside another component creates a new type on every render, so its state (and the text in its input) is lost each time. Declare components at the top level.
Hooks questions
“What are the Rules of Hooks?”
react.dev gives two rules:
- Only call Hooks at the top level: not inside loops, conditions, nested functions or
try/catch/finallyblocks, and before any earlyreturn. - Only call Hooks from React functions: function components and custom Hooks, not regular JavaScript functions, class components or event handlers.
React relies on Hooks being called in the same order on every render to match each call with its state. The one documented exception is use, which React 19 lets you call conditionally.
“When does useEffect run, and what is the cleanup for?”
An Effect runs after React commits to the screen. With a dependency array, it re-runs when a dependency changes; the cleanup function runs before the next run and when the component unmounts. Cleanup is how you disconnect, unsubscribe, or ignore a stale fetch:
useEffect(() => {
let ignore = false;
fetchResults(query).then((data) => {
if (!ignore) setResults(data);
});
return () => {
ignore = true;
};
}, [query]);
Without the ignore flag, a slow response for an old query can overwrite the results for the new one: a race condition.
“When should you not use an Effect?”
This question separates candidates who read the docs. react.dev calls Effects “an escape hatch” for synchronizing with external systems (the network, browser APIs, non-React widgets, subscriptions). You don’t need one to:
- Derive data: calculate it during render (
const fullName = first + ' ' + last), and wrap expensive calculations inuseMemo. - Respond to a user action: put the code in the event handler, because an Effect can’t know which button was clicked.
- Reset state when a prop changes: pass a
keyinstead. - Chain state updates: compute the next state in the handler rather than in a cascade of Effects.
For subscribing to an external store, the docs recommend useSyncExternalStore over a hand-written Effect.
“Why does my Effect run twice in development?”
That’s Strict Mode. In development it re-renders components an extra time to find impure rendering, and runs one extra setup, cleanup, setup cycle for every Effect “to find bugs caused by missing Effect cleanup.” None of it happens in production. The fix is a correct cleanup function, not turning Strict Mode off.
“useRef vs useState?”
Both persist across renders. Changing state queues a re-render; changing ref.current doesn’t. Use a ref for values that don’t affect what’s drawn (a timer ID, a DOM node, the previous value) and state for anything the UI shows.
“When would you use useReducer or Context?”
useReducer puts complex update logic in one pure function ((state, action) => nextState), which helps when many events change related state. Context passes a value deep into the tree without threading props through every level (prop drilling). Context isn’t a state manager by itself: every component reading it re-renders when the value changes, so keep context values focused, or reach for an external store when updates are frequent and widely shared.
“What’s a custom Hook?”
A function whose name starts with use and that calls other Hooks, so components can share stateful logic (each call gets its own state). useOnlineStatus or useDebouncedValue are typical examples.
Performance questions
“How do you make a slow React screen faster?”
Measure first (React DevTools Profiler; React 19.2 also added Performance Tracks to Chrome DevTools), then:
- Avoid unnecessary renders: keep state as low in the tree as possible, split components, and memoize where it helps.
- Don’t block typing: mark non-urgent updates with
useTransition, or show a deferred value withuseDeferredValue. - Load less: split code with
lazyandSuspense, and virtualize very long lists. - Fix the data: fetch in parallel, cache, and avoid waterfalls.
“When do you use memo, useMemo and useCallback, and does the React Compiler change that?”
memo skips re-rendering a component when its props haven’t changed; useMemo caches a calculated value; useCallback caches a function so a memoized child doesn’t see a new prop each render. Since React Compiler 1.0 (October 2025), the compiler can do this memoization automatically. Its announcement says useMemo and useCallback “can continue to be used” as an escape hatch, for example when a memoized value is an Effect dependency, and recommends leaving existing memoization in place rather than ripping it out. Expo SDK 54 enables the compiler by default, and the Vite and Next.js starters offer compiler-enabled templates.
React 19 and modern React questions
“What changed in React 19?”
The highlights from the React 19 release post:
- Actions: async functions run in transitions, with pending state, errors and optimistic updates handled for you.
useActionStatereturns an Action’s last result and a pending flag;useFormStatusreads the status of the parent<form>;useOptimisticshows the expected result while a request is in flight.usereads a promise or context during render, and unlike other Hooks it “can be called conditionally.”refas a prop: new function components no longer needforwardRef.- Context as a provider:
<ThemeContext value="dark">instead of<ThemeContext.Provider>. - Document metadata:
<title>,<meta>and<link>rendered in a component are hoisted to<head>. - Server Components are stable, and Server Actions (marked
'use server') let client components call server functions.
“Explain Server Components vs Client Components.”
Server Components run on the server (at build time or per request), can read data directly, and send no JavaScript of their own to the browser. Client Components are marked with 'use client' at the top of the file and run in the browser too, so they can use state, Effects and event handlers. A good answer explains the boundary: a Server Component can render a Client Component and pass it serializable props, and you keep interactivity in small client leaves. Mention that the React team published security advisories for Server Components in December 2025, so keeping React and your framework patched matters.
“What came after 19.0?”
React 19.2 (October 2025) added <Activity>, which hides part of the UI while keeping its state, useEffectEvent for “event” logic inside Effects that shouldn’t re-run them, and partial pre-rendering in React DOM. React 19.3 (September 2026) made <ViewTransition> stable for animating changes made in transitions, and stabilized refs on Fragments. You won’t be expected to know every API, but knowing the current version shows you keep up.
“How do you catch rendering errors?”
With an error boundary: a class component that implements static getDerivedStateFromError (to render a fallback) and componentDidCatch (to log). The docs say “there is currently no way to write an Error Boundary as a function component,” and point to the react-error-boundary package if you’d rather not write the class yourself.
“How would you start a new React app today?”
Not with Create React App, which the React team deprecated for new apps in February 2025. The docs recommend a framework (Next.js, React Router or Expo), and for unusual constraints a build tool such as Vite, Parcel or Rsbuild. Their rule of thumb: “if your app needs routing, you would probably benefit from a framework.”
Scenario questions for senior React developers
Interviewers give you a symptom and listen to how you reason. Say what you’d check first, then the fix.
| Symptom | What’s happening | Fix |
|---|---|---|
| Search results flash old data when typing fast | Responses arrive out of order (a race condition) | Ignore stale responses in the Effect cleanup, or use a data library that cancels requests |
| An input loses its text whenever the parent re-renders | A component is defined inside another, so it’s a new type each render | Move the component definition to the top level |
| Editing one row of a list edits the wrong row after sorting | Index used as key | Use a stable ID from the data |
| An Effect runs twice in development | Strict Mode’s extra setup and cleanup cycle | Write the cleanup (disconnect, unsubscribe, ignore) |
| Typing in a filter box feels laggy on a big list | The expensive list re-renders on every keystroke | useDeferredValue or useTransition, memoize the list, virtualize it |
| A form double-submits and shows no progress | Submission state handled by hand | An Action with useActionState or useFormStatus for pending state |
| One failing widget blanks the whole page | No error boundary around it | Wrap risky sections in error boundaries with a useful fallback |
For front-end system design (“design an autocomplete”, “design a news feed”), walk through requirements, the component tree, where state lives, data fetching and caching, loading and error states, accessibility (keyboard and screen reader) and performance. Our system design interview guide covers the general method.
Live coding: what to expect
Common exercises: a counter or todo list (state and lists with keys), a debounced search with loading and error states (Effects and cleanup), tabs or an accordion (lifting state, accessibility), a modal (portals, focus), and fetching data and rendering a table. Talk while you code: state your plan, name the edge cases (empty, loading, error, slow network), and test as you go. For take-home exercises, see our take-home assignment guide.
Behavioral questions for React developers
Answer these with a specific story using the STAR method: situation, task, the actions you took, and the result.
- “Tell me about a performance problem you found and fixed.”
- “Describe a time you disagreed with a designer or product manager about the UI.”
- “How do you make sure what you build is accessible?”
- “Tell me about a bug that reached production. What did you change afterwards?”
- “How do you review a teammate’s React code?”
For the rest of the stack, see our full-stack developer interview questions and the software engineer mock interview questions.
Frequently asked questions
What React questions are asked in interviews?
Is the virtual DOM still a good interview answer?
Do I still need useMemo and useCallback with the React Compiler?
What’s new in React 19 that interviewers ask about?
How should I prepare for a senior React interview?
Can Huru help me practice React interview questions?
Sources
- React, React v19 (December 5, 2024). Read on 26 October 2026.
- React, React 19.2 (October 1, 2025) and React 19.3 (September 9, 2026). Read on 26 October 2026.
- React, React Compiler v1.0 (October 7, 2025) and Sunsetting Create React App (February 14, 2025). Read on 26 October 2026.
- React docs: Render and Commit, Rendering Lists, Preserving and Resetting State, You Might Not Need an Effect, Rules of Hooks, StrictMode, Component (error boundaries). Read on 26 October 2026.
- React blog, security advisories for React Server Components (December 3, 2025 and December 11, 2025).