Skip to main content

Expert React Interview Questions

Curated Expert-level React interview questions for developers targeting expert positions. 30 questions available.

Last updated:

React Interview Questions & Answers

Skip to Questions

Welcome to our comprehensive collection of React interview questions and answers. This page contains expertly curated interview questions covering all aspects of React, from fundamental concepts to advanced topics. Whether you're preparing for an entry-level position or a senior role, you'll find questions tailored to your experience level.

Our React interview questions are designed to help you:

  • Understand core concepts and best practices in React
  • Prepare for technical interviews at all experience levels
  • Master both theoretical knowledge and practical application
  • Build confidence for your next React interview

Each question includes detailed answers and explanations to help you understand not just what the answer is, but why it's correct. We cover topics ranging from basic React concepts to advanced scenarios that you might encounter in senior-level interviews.

Use the filters below to find questions by difficulty level (Entry, Junior, Mid, Senior, Expert) or focus specifically on code challenges. Each question is carefully crafted to reflect real-world interview scenarios you'll encounter at top tech companies, startups, and MNCs.

Questions

30 questions
Q1:

How does React Fiber implement cooperative scheduling using the call stack without blocking the main thread?

Expert

Answer

Fiber creates a linked list tree where each unit of work is a fiber node. Instead of recursively calling functions, React manually iterates the tree, yielding control back to the browser using shouldYield so higher-priority events can run, enabling cooperative multitasking.
Quick Summary: Fiber implements cooperative scheduling using a linked-list work loop instead of the call stack. Each fiber is one unit of work. React's scheduler checks if there's a higher-priority task or a frame deadline after completing each fiber. If yes, it yields control to the browser, then resumes from where it left off. No call stack explosion, no blocking.
Q2:

Why does React split rendering into begin work and complete work phases inside the reconciler?

Expert

Answer

beginWork calculates changes and creates or updates child fibers, while completeWork builds DOM nodes or side-effect lists. This separation allows React to pause between units of work for better concurrency.
Quick Summary: Begin work processes a fiber top-down — determining what children it renders, creating child fibers, reconciling with previous renders. Complete work processes a fiber bottom-up — collecting effects, building the updated props, and assembling the result. This two-pass structure lets React walk the tree once without recursion.
Q3:

How does React handle priority inversion when low-priority tasks block high-priority UI updates?

Expert

Answer

React uses lanes and entanglement mapping so high-priority lanes interrupt low-priority work. React reuses partial work and discards stale renders to maintain responsiveness.
Quick Summary: React's scheduler uses exponential backoff for low-priority tasks that get preempted repeatedly. If a low-priority task keeps getting interrupted, its priority gradually increases to prevent starvation. High-priority tasks (user input, Discrete events) get their own lane and always preempt lower lanes.
Q4:

How does React store and compare alternate trees to guarantee atomic commits?

Expert

Answer

Each component has a current fiber and a work-in-progress fiber. During commit, React swaps pointers atomically to avoid partial UI updates.
Quick Summary: React maintains a "current" fiber tree (displayed UI) and a "work-in-progress" tree (being computed). All changes happen on the work-in-progress tree. Only when the entire tree is computed and reconciled does React atomically swap the two — flipping a single pointer. The current tree becomes the previous tree for the next render.
Q5:

How does React’s diffing algorithm optimize keyed vs non-keyed lists internally?

Expert

Answer

Keyed diffing builds a keyed map to detect moves, deletions, and insertions. Non-keyed diffing assumes positional alignment, which is faster but incorrect for reordering.
Quick Summary: For keyed lists, React builds a map of key → fiber, then matches new elements to existing fibers by key — O(n) instead of O(n²) comparison. For non-keyed lists, React compares by position. Keys allow React to detect moves, insertions, and deletions precisely, reusing DOM nodes for moved items instead of destroying and recreating them.
Q6:

How does React optimize Suspense boundaries through early reveal and delayed placeholder strategies?

Expert

Answer

React reveals resolved subtrees early and delays fallback rendering to avoid flicker using revealTimers and cache heuristics.
Quick Summary: React uses two strategies: if data resolves quickly (under ~250ms), React delays showing the fallback at all — the content appears directly. If data is slow, React shows the fallback immediately. This prevents unnecessary fallback flashes for fast connections while still providing feedback for slow ones.
Q7:

Why are Promise boundaries essential in the React 19 use hook implementation?

Expert

Answer

The use hook integrates directly into the fiber loop. When a promise is encountered, React suspends the fiber, stores continuation, and retries when resolved—similar to coroutines.
Quick Summary: The use hook throws a Promise when data isn't ready — React catches it via a try/catch around the component render. React stores the Promise internally, subscribes to its resolution, and when the Promise resolves, React schedules a re-render of that Suspense boundary. Promise boundaries make throwing-as-control-flow predictable.
Q8:

How does React ensure that streamed SSR content from the server matches hydration order on the client?

Expert

Answer

React tags streamed chunks with react-id markers and uses a hydration priority queue to hydrate components in the correct order.
Quick Summary: React streaming SSR sends HTML chunks with embedded script tags containing data for each Suspense boundary. On the client, React processes these chunks in order, using a list-based hydration queue. If chunks arrive out of order (HTTP/2 push), React buffers and applies them in the correct sequence using their boundary IDs.
Q9:

Why is Suspense fundamentally incompatible with synchronous rendering models?

Expert

Answer

Suspense requires pausing and resuming rendering. Synchronous models cannot interrupt execution, making Suspense impossible without async fiber architecture.
Quick Summary: Suspense requires the rendering model to be interruptible — a component can stop mid-render (by throwing a Promise) and resume later. Synchronous rendering models run to completion; they have no mechanism to suspend mid-tree and resume later. Concurrent mode's interruptible fiber architecture is a prerequisite for Suspense to work.
Q10:

How does React avoid memory explosion when many suspended components are waiting for promises?

Expert

Answer

React uses ref-counted wakeable objects and deduplicates promise listeners to prevent memory overhead.
Quick Summary: React deduplicates suspended Promises — if multiple components suspend on the same Promise, React only resolves it once. Resolved Promise results are cached in the fiber tree during the current render, then discarded when the render commits. React doesn't hold large Promise result buffers — it resolves, commits, and moves on.
Q11:

Explain how React reconciler uses bailing out to skip unnecessary subtrees during rendering.

Expert

Answer

React skips reconciliation when props, state, and context are unchanged via shallow comparison, reusing the previous fiber subtree.
Quick Summary: Bailing out means React skips rendering a subtree entirely when it can prove the output won't change. This happens when React.memo comparison passes, when useState returns the same value, or when a Context consumer's consumed value hasn't changed. React short-circuits the fiber work loop for that subtree — no reconciliation, no diffing, no DOM work.
Q12:

How does React optimize large forms where controlled inputs cause heavy re-renders?

Expert

Answer

React uses batched updates, event priority, offscreen rendering, browser input buffering, or hybrid refs for better performance.
Quick Summary: For large forms, avoid controlled inputs for fields that don't need real-time validation — use uncontrolled inputs (via refs) or form libraries like React Hook Form that minimize re-renders. Split the form into smaller components so only the changed field's component re-renders. Debounce expensive derived state computations.
Q13:

Why is the React Server Components architecture inherently more cacheable than client-rendered components?

Expert

Answer

RSC output is serializable and dependency-tracked, enabling fine-grained caching at the module or function level.
Quick Summary: Server Components produce a static output determined by their props and server-side data — same inputs always produce the same output. This output can be cached at the edge (CDN) or in memory. Client Components depend on browser state (user input, events) — inherently dynamic, not cacheable. Moving logic to Server Components improves cacheability.
Q14:

How does React prevent stale hydration attachments when HTML streaming arrives out of order?

Expert

Answer

React buffers out-of-order chunks and only hydrates them when boundary segments are complete.
Quick Summary: React assigns each Suspense boundary a unique ID in the HTML stream. When streaming HTML chunks arrive, React's client-side code matches each chunk to its boundary ID. If chunks arrive out of order, React buffers them. DOM insertion happens in the correct boundary order regardless of network delivery order.
Q15:

What is the progressive selective hydration algorithm introduced in React 18?

Expert

Answer

React hydrates based on interaction priority, visibility, and lane scheduling to reduce blocking time.
Quick Summary: Progressive selective hydration prioritizes hydrating Suspense boundaries that the user interacts with first. If a user clicks on a not-yet-hydrated area, React interrupts other in-progress hydration work, hydrates that specific boundary immediately (making it interactive), then resumes hydrating the rest in background.
Q16:

Why can React’s lane model guarantee deterministic rendering even under concurrency?

Expert

Answer

Lane priorities, expiration times, and entanglement rules ensure predictable update ordering.
Quick Summary: React's lane model assigns each update to a specific bit in a lane bitmask (32-bit integer). Each lane represents a priority level. React processes lanes in priority order. Because lanes are bitmask operations (fast) and priorities are fixed, React can deterministically schedule and merge concurrent updates — the result is always the same for the same inputs.
Q17:

Why can mixing Context Providers deeply inside rendering loops cause reconciler thrashing?

Expert

Answer

Each Provider update invalidates all consumers; inside loops, this causes exponential rerenders.
Quick Summary: Creating Context Providers inside rendering loops means each render creates new Context values and potentially new Provider component instances. This busts the Context value comparison, causing all consumers to re-render. Providers that recreate their value on every render of a parent cause "Context thrashing" — constant reconciler work for no real change.
Q18:

How does React 19 handle action revalidation to avoid inconsistent states across the app?

Expert

Answer

React invalidates cached RSC trees referencing stale data and regenerates affected segments using dependency graph invalidation.
Quick Summary: React 19 server actions trigger revalidation after mutation — by default, the current route's data is re-fetched and the component tree is re-rendered with fresh data. You can control revalidation scope with revalidatePath or revalidateTag. This ensures state is consistent post-action without manual cache invalidation.
Q19:

Explain the internals of useSyncExternalStore and how it guarantees tear-free reads.

Expert

Answer

React ensures atomic snapshot reads and compares server/client snapshots, preventing tearing during concurrent renders.
Quick Summary: useSyncExternalStore takes a subscribe function and a getSnapshot function. On render, React calls getSnapshot and renders with that value. It also registers a listener via subscribe. If the store changes during a concurrent render, React compares the new snapshot — if different from the render-time snapshot, it re-renders synchronously to prevent tearing.
Q20:

How does React dedupe heavy selectors inside Context and Redux with concurrent rendering?

Expert

Answer

React caches derived values via memoized selectors and fine-grained subscriptions.
Quick Summary: useSyncExternalStore and libraries like Jotai/Zustand expose stable selectors — only components using a specific slice subscribe to changes in that slice. With concurrent rendering, Redux and Context use subscription models that check current vs previous values before re-rendering. Memoized selectors that return stable references prevent cascade re-renders.
Q21:

What happens when a Server Component imports a Client Component that imports another Server Component?

Expert

Answer

React fails the build. Server Components cannot appear under Client boundaries.
Quick Summary: A Server Component that imports a Client Component is fine — the Client Component is marked for client-side rendering. But a Client Component can't import a Server Component directly because the Client Component is in the client bundle and Server Components must never be. However, a Server Component can pass a Server Component as a JSX prop (children) to a Client Component.
Q22:

How does React resolve cyclic dependency chains in async Suspense trees?

Expert

Answer

React tracks pending wakeables and detects repeated suspension cycles, surfacing errors to boundaries.
Quick Summary: React tracks already-resolved Suspense trees in the fiber structure. When a suspended Promise in an async tree depends on another suspended Promise, React resolves them in dependency order. React deduplicates identical Promises (same reference) and resolves the dependency chain bottom-up, retrying parent boundaries when child dependencies resolve.
Q23:

How does the fiber system reuse DOM nodes while swapping fiber trees?

Expert

Answer

DOM nodes attach to the hostFiber. During commit, React updates props/events without destroying nodes.
Quick Summary: During commit, React walks the work-in-progress fiber tree and matches each fiber to an existing DOM node. If the fiber's type and key match the current DOM node, React updates it in-place (reuses the node). If they don't match, React removes the old node and inserts the new one. DOM node reuse minimizes browser layout recalculation.
Q24:

What is the transition tree and how does React use it during low-priority renders?

Expert

Answer

React marks updates inside startTransition as belonging to a separate transition tree that can pause, resume, or discard work.
Quick Summary: The transition tree is the work-in-progress tree being built for a low-priority transition update. React renders it concurrently alongside the current tree. If an urgent update arrives, React abandons the transition tree, handles the urgent update on the current tree, and then starts a new transition tree incorporating all pending updates.
Q25:

How does React implement high-priority interruptions during slow list diffing operations?

Expert

Answer

React checks scheduler signals; shouldYield() pauses reconciliation to let high-priority tasks run.
Quick Summary: React's scheduler uses postMessage to break work into tasks. Each task processes fibers until the frame budget (~5ms) is exhausted, then yields. A high-priority interrupt (user input) is registered in the scheduler queue with a higher priority. On the next scheduler cycle, it runs the high-priority task first before resuming list diffing.
Q26:

What are hydration bubbles and how does React use them to allow partial interactive UI?

Expert

Answer

Hydration bubbles hydrate children first, then expand upward, enabling selective interactivity.
Quick Summary: Hydration bubbles are the units of progressive hydration — each Suspense boundary is a bubble that hydrates independently. React attaches event listeners to the document root before hydration completes (delegation). When a user interacts with an unhydrated bubble, React synchronously hydrates just that bubble and replays the event.
Q27:

How does React’s event system maintain compatibility with concurrent rendering?

Expert

Answer

React replays events fired before hydration finishes, ensuring consistent event processing.
Quick Summary: React uses a root-level event listener (attached to the container div) for all synthetic events. In concurrent mode, events are processed after the current render commits, not during. React stores the event, commits the render, then dispatches it. This guarantees event handlers always see a fully consistent, committed DOM state.
Q28:

Why does React avoid triggering layout thrashing even with layout effects?

Expert

Answer

React batches DOM reads/writes into phases to avoid bouncing layout calculations.
Quick Summary: useLayoutEffect runs synchronously after DOM mutations but before the browser paints. React batches all useLayoutEffect callbacks and runs them together after the commit. Because this happens in the same synchronous execution context as the DOM write, the browser doesn't get a chance to paint between the write and the layout measurement — no thrash.
Q29:

How does React determine when an effect cleanup should run during concurrent re-renders?

Expert

Answer

React only cleans up effects from committed renders; work-in-progress renders are discarded without cleanup.
Quick Summary: Effect cleanup timing in concurrent mode: React runs cleanup when a component unmounts, or before re-running an effect. In concurrent mode, React may start rendering a component, then abort and discard it before committing — effects don't run for aborted renders. Cleanup runs only for effects that were actually committed to the DOM.
Q30:

How does the React compiler React Forget optimize component re-renders automatically?

Expert

Answer

React Forget auto-generates memoization logic, stabilizing references and eliminating the need for manual useMemo/useCallback.
Quick Summary: React Forget (the React compiler) statically analyzes component code and automatically inserts useMemo and useCallback where values are stable across renders. Instead of manually memoizing, the compiler identifies which values can be reused and generates the memoization code for you. Goal: performance of memoized code without the manual effort.

Curated Sets for React

No curated sets yet. Group questions into collections from the admin panel to feature them here.

Ready to level up? Start Practice