Interview Questions on React JS for Experienced Developers

Interview questions on React JS for 2026: basic React JS questions, experienced hooks and architecture, scenario-based senior prep, React 19, and live coding answers.

Published

Updated

Tech reviewed byDeepak Prasad

Interview Questions on React JS for Experienced Developers

Interview questions on React JS in 2026 span basic JSX and state through experienced architecture—Fiber scheduling, Server Components, and production debugging. Interview questions on React JS for experienced candidates add scenario-based rounds: fix an infinite useEffect loop, design a dashboard data layer, or defend why you picked TanStack Query over Context. Basic interview questions on React JS still matter because senior loops often start with fundamentals before whiteboard depth.

Below are 45 questions organized from basic through experienced to scenario-based answers, each with elaborate explanations; technical sections include a strong answer sample. For a companion guide with additional coding drills and hook depth, see React interview questions and answers. For TypeScript interview questions (component props, event types, generics), see TypeScript interview questions. Pair with front end developer interviews for HTML/CSS/browser fundamentals, full stack developer interviews for API integration, Node.js interviews for backend pairing, and Angular interviews when interviewers compare frameworks.

NOTE
Prep target: Master basics (props, state, keys) even for senior roles—then rehearse scenarios aloud: debounced search, stale closure fix, slow dashboard triage, and React 19 Actions vs hand-rolled fetch state.

Tested on: Ubuntu 25.04 (Plucky Puffin); kernel 6.14.0-37-generic; Node.js 20.18.2 for debounce and immutable-update simulations.


Interview context and how to prepare

What do interview questions on React JS actually test?

React loops test whether you can ship correct UI as state changes—not whether you memorized 2018 lifecycle diagrams.

Layer What interviewers probe
Basics Components, JSX, props, state, lists
Hooks useState, useEffect, deps, custom hooks
Rendering Reconciliation, keys, when re-renders happen
Data Fetch patterns, TanStack Query, error handling
Experienced RSC, concurrency, perf profiling
Scenarios Debug loops, architecture trade-offs, live coding
Level Emphasis
Basic Controlled forms, keys, one-way data flow
Experienced (3–6 yr) State architecture, testing, API integration
Senior (6+ yr) System design, RSC, team standards, incidents
Basic vs experienced React JS interview questions — what changes?
Basic questions Experienced / scenario questions
What is JSX? Why did this useEffect loop infinitely?
Props vs state Design data flow for admin table + filters
What are hooks? When RSC vs client component for this page?
Controlled input Debounce search without jank—walk through code
Virtual DOM definition Profile dashboard—what do you measure first?

Experienced rounds assume you already know basics and push judgment under ambiguity.

How are scenario-based React interviews structured?

Typical flow:

  1. Situation — "Search re-fetches every keystroke and UI janks"
  2. Your diagnosis — missing debounce, no abort, parent re-render
  3. Fix — debounce + AbortController or TanStack Query
  4. Follow-up — "What if user types faster than network?"

Common scenario rounds include an infinite useEffect loop, child re-renders when props look unchanged, hydration mismatch, and large lists without virtualization.

What is a realistic prep plan for React JS interviews?
Week Focus Output
1 Basic — JSX, props, state, lists, forms Todo without tutorial
2 Hooks — effects, cleanup, custom hooks useDebounce from scratch
3 Data — loading/error, Query vs useEffect Paginated list
4 Experienced — perf, Context vs store, testing Profiler screenshot story
5 Scenarios — timed debug + coding 3 scenario narrations
6 React 19 + mock Actions, useOptimistic, whiteboard

Basic interview questions on React JS

What is React JS?

React is a JavaScript library for building user interfaces with a component-based, declarative model—you describe UI as a function of state; React updates the DOM when state changes.

Idea Meaning
Components Reusable UI units (Button, UserCard)
Declarative Describe what UI should look like
One-way data flow Props down, events up
Ecosystem Next.js, Remix, React Native

React is not a full framework—you choose routing, global state, and styling.

A strong answer is:

React is a component library for declarative UIs with predictable data flow—I use it when rich client interactivity and ecosystem depth matter.

What is JSX?

JSX embeds HTML-like syntax in JavaScript; compilers transform it to React.createElement calls.

jsx
function Welcome({ name }) {
  return <h1>Hello, {name}</h1>;
}

Rules: one parent (or Fragment), className not class, expressions in {}, close all tags.

A strong answer is:

JSX is syntax sugar for readable component trees—it compiles to JavaScript and is not a separate language or browser feature.

What is a React component?

A component is a function (or class) that returns UI. Function components are standard in 2026; hooks supply state and effects.

jsx
function Counter() {
  const [count, setCount] = React.useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

Components compose—pages are trees of smaller components.

A strong answer is:

A component is a reusable UI function with optional state—composition lets me build pages from small pieces instead of monolithic templates.

What are props?

Props (properties) are read-only inputs from parent to child—one-way data flow.

jsx
function Avatar({ src, alt }) {
  return <img src={src} alt={alt} />;
}

Children can be passed as props.children. Props must not be mutated by the child.

A strong answer is:

Props flow down and are immutable in the child—I treat them as function arguments for UI rendering.

What is state in React?

State is data that changes over time inside a component. When state updates, React re-renders the component.

Props State
Source Parent Local (or lifted)
Mutable by component No Yes (via setter)
Triggers re-render When parent re-renders When setter called

Lift state up when siblings need to share it.

A strong answer is:

State is mutable local data that drives UI—when it changes, React re-renders; I lift state to the lowest common ancestor when siblings must share it.

Controlled vs uncontrolled components?
Type Source of truth Example
Controlled React state value={text} onChange={...}
Uncontrolled DOM ref to read input value

Basic interviews favor controlled inputs—predictable, testable, easy validation.

A strong answer is:

Controlled components keep form state in React—I default to them for forms unless I need file inputs or third-party widgets that fight controlled mode.

What is the Virtual DOM?

React builds an in-memory element tree representing UI. On update, React diffs the new tree against the previous and applies minimal DOM changes.

Fiber (React 16+) enables incremental reconciliation and concurrent rendering—work can pause and resume.

A strong answer is:

Virtual DOM is React's lightweight UI representation for efficient diffing—Fiber underneath enables priorities and concurrent features, not just a simple full-tree compare.

Why do lists need keys?

Keys help React identify which items changed, were added, or removed—stable identity across renders.

jsx
{items.map((item) => <li key={item.id}>{item.name}</li>)}
Key choice Result
Stable unique id Correct reuse
Array index Bugs on reorder/delete

A strong answer is:

Keys must be stable unique ids—not array index when the list can reorder or delete, or React reuses wrong component state.

What is one-way data flow?

Data flows down via props; events flow up via callbacks. Parents own shared state; children request changes through handlers.

This predictability simplifies debugging—trace props from root.

A strong answer is:

One-way flow means parents own state and pass callbacks—no child silently mutating parent data, which keeps large trees debuggable.

How do you conditionally render in React?

Patterns:

jsx
{isLoggedIn ? <Dashboard /> : <Login />}
{error && <ErrorBanner message={error} />}
{items.length === 0 ? <Empty /> : <List items={items} />}

Prefer explicit branches for complex cases over nested ternaries.

A strong answer is:

I use ternary or short-circuit for simple cases and early returns or small subcomponents when conditional UI grows—readability beats clever one-liners.

What are React Fragments?

Fragments group children without extra DOM nodes:

jsx
return (
  <>
    <Title />
    <Body />
  </>
);

Avoids wrapper <div> that breaks CSS layout or semantics.

A strong answer is:

Fragments let me return multiple siblings without a useless wrapper div that would break flex or grid layouts.


Hooks, rendering, and mid-level depth

What are the rules of hooks?
  1. Call hooks only at the top level—not inside loops, conditions, or nested functions
  2. Call hooks only from React function components or custom hooks

Why: React relies on call order to associate state with each hook instance.

A strong answer is:

Hooks must run in the same order every render—I never put useState inside an if, or state slots get misaligned and bugs become nightmare fuel.

How does useState work?

useState returns [value, setter]. Updates schedule a re-render. Setters accept a value or functional updater prev => next.

javascript
let count = 0;
const queue = [];
const setCount = (update) => { queue.push(update); };
const flush = () => {
  queue.forEach((u) => { count = typeof u === "function" ? u(count) : u; });
  queue.length = 0;
};

setCount(count + 1);
setCount(count + 1);
flush();
console.log("batched direct:", count);

count = 0;
setCount((c) => c + 1);
setCount((c) => c + 1);
flush();
console.log("batched functional:", count);
Output

Running prints batched direct: 1 then batched functional: 2—when React batches updates, direct setCount(count + 1) reads the same stale render value twice; functional updaters chain correctly.

A strong answer is:

useState queues re-renders on update—I use functional setState when the next value depends on the previous, especially in async or batched callbacks.

What does useEffect do?

useEffect runs side effects after paint—fetch, subscriptions, DOM sync.

jsx
useEffect(() => {
  document.title = `Count: ${count}`;
}, [count]);
Dependency array Behavior
Omitted Every render (rare, risky)
[] Mount + unmount only
[a, b] When a or b change

Return a cleanup function for teardown.

A strong answer is:

useEffect is for synchronizing with external systems after render—I declare dependencies explicitly and return cleanup for subscriptions and abort controllers.

What is the stale closure problem in useEffect?

Effects close over values from the render when they were created. If dependencies are wrong, the effect sees old state/props.

Fix:

  • List all reactive values in dependency array
  • Use functional updates for state
  • useRef for latest value in long-lived callbacks

A strong answer is:

Stale closures happen when effects capture old renders—I fix dependency arrays, functional setState, or refs for values that must stay current in timers and subscriptions.

When do you use useMemo and useCallback?
Hook Memoizes Use when
useMemo Computed value Expensive derive; stable object for child memo
useCallback Function reference Stable callback for memoized child

React 19 Compiler auto-memoizes in many codebases—still explain when manual memo helps (uncompiled paths, library boundaries).

Do not wrap everything—memo has cost.

A strong answer is:

I memoize only when profiling shows wasted child work or expensive derivation—not by default; React 19's compiler reduces manual memo over time.

What is useRef used for?

useRef holds a mutable box that persists across renders without causing re-render when .current changes.

Uses: DOM refs, timer ids, AbortController, latest value for callbacks.

A strong answer is:

useRef stores values that survive renders but shouldn't trigger them—DOM nodes, interval ids, or latest props for event handlers.

What are custom hooks?

Functions starting with use that compose built-in hooks—reusable stateful logic.

jsx
function useDebounce(value, delayMs) {
  const [debounced, setDebounced] = useState(value);
  useEffect(() => {
    const id = setTimeout(() => setDebounced(value), delayMs);
    return () => clearTimeout(id);
  }, [value, delayMs]);
  return debounced;
}

Custom hooks share logic, not state—each call gets isolated state.

A strong answer is:

Custom hooks extract reusable behavior—debounce, fetch, media query—without duplicating effect logic across components.

When do you prefer useReducer over useState?

useReducer suits complex state transitions with multiple actions—forms with many fields, wizards, state machines.

javascript
function todosReducer(state, action) {
  switch (action.type) {
    case "add":
      return [...state, { id: action.id, text: action.text, done: false }];
    case "toggle":
      return state.map((t) =>
        t.id === action.id ? { ...t, done: !t.done } : t
      );
    default:
      return state;
  }
}

let state = [];
state = todosReducer(state, { type: "add", id: 1, text: "learn" });
state = todosReducer(state, { type: "toggle", id: 1 });
console.log(state[0].done);
Output

Running prints true—immutable updates in the reducer keep state predictable.

A strong answer is:

useReducer when next state depends on action type and prior state in non-trivial ways—todo apps, multi-step flows—not for a single boolean toggle.

What is lifting state up?

Move shared state to the closest common ancestor of components that need it; pass data and callbacks down.

Avoids duplicate sources of truth and sync bugs between siblings.

A strong answer is:

I lift state to the parent that owns the shared truth—two siblings editing the same filter share one state object and callbacks, not duplicated useState.

When should you use React Context?

Context passes data through the tree without prop drilling—theme, locale, auth session.

Good for Poor for
Low-churn global UI settings High-frequency updates (causes wide re-renders)
Auth user object Large app state (prefer colocation + Query/store)

Split contexts by update frequency when needed.

A strong answer is:

Context for rarely changing cross-cutting data—I split contexts or use selectors/stores when updates are frequent to avoid re-rendering the whole tree.


Interview questions on React JS for experienced developers

What is React Fiber?

Fiber is React's reconciliation engine—each unit of work is a fiber node representing a component instance.

Enables:

  • Incremental rendering — pause and resume
  • Priorities — urgent updates (input) before transitions
  • Concurrent featuresuseTransition, useDeferredValue

Experienced interviews use Fiber to explain why effects run after paint and why strict mode double-invokes effects in dev.

A strong answer is:

Fiber is the work unit for reconciliation—it enables concurrent rendering and priority scheduling, which explains effect timing and interruptible updates.

What is concurrent rendering?

React can start, pause, and abandon renders to keep UI responsive. useTransition marks non-urgent updates; useDeferredValue lags behind fast-changing input.

jsx
const [isPending, startTransition] = useTransition();
startTransition(() => setFiltered(hugeFilter(query)));

Not the same as async/await—it's scheduling, not parallelism.

A strong answer is:

Concurrent rendering keeps typing responsive while heavy filters catch up—I use transitions for non-urgent UI updates, not as a replacement for proper data fetching architecture.

What are React Server Components (RSC)?

Server Components run on the server only—they never ship component JavaScript to the client for those modules. They can read databases and filesystem directly.

Server Component Client Component ("use client")
No useState/useEffect Hooks, browser APIs, interactivity
Zero client bundle for logic Ships JS to browser
Serialize props to client tree Receives serialized props

Frameworks like Next.js App Router compose both in one tree.

A strong answer is:

RSC moves data-heavy, non-interactive UI to the server—client components handle interactivity; I don't put useEffect fetch on server components.

What are React 19 Actions and useActionState?

Actions are async functions integrated with forms—React tracks pending, error, and result state.

jsx
const [state, formAction, isPending] = useActionState(saveUser, null);
// <form action={formAction}>...</form>

useFormStatus lets child buttons read parent form pending state without prop drilling.

Reduces manual useState + try/catch boilerplate for mutations.

A strong answer is:

React 19 Actions standardize form mutation lifecycle—useActionState replaces hand-rolled loading/error flags for many server-action forms.

What is useOptimistic?

useOptimistic shows optimistic UI while an async action runs—reverts automatically on failure.

Useful for likes, comments, cart updates where perceived speed matters.

A strong answer is:

useOptimistic gives first-class optimistic UI with rollback—I use it when users expect instant feedback and the server may still fail.

TanStack Query vs useEffect for data fetching?
useEffect + fetch TanStack Query
Caching Manual Built-in
Deduping Manual Automatic
Stale/refetch Manual staleTime, window focus
Loading/error Manual flags Standardized

Experienced teams default to Query (or similar) for server state; useEffect fetch is a code smell in large apps unless justified.

A strong answer is:

I use TanStack Query for server state—cache, dedupe, invalidation—useEffect fetch only for rare one-off side effects, not every list page.

What are error boundaries?

Class components (or library wrappers) implementing getDerivedStateFromError / componentDidCatch catch render errors in children—show fallback UI instead of white screen.

They do not catch event handlers, async, or SSR errors alone.

A strong answer is:

Error boundaries isolate render failures per route or widget—I pair them with route-level fallbacks and logging, not try/catch around every onClick.

How do you test React components?

React Testing Library — test behavior users see, not implementation details.

Practice Why
Query by role/label Accessibility-aligned
userEvent over fireEvent Realistic interaction
Mock network at HTTP layer Stable integration tests
Avoid testing internal state Refactor-friendly

A strong answer is:

I test what users see—roles, labels, outcomes—not component state or hook call counts, so refactors don't break tests unnecessarily.

How do you reduce React bundle size?
Technique Use
Route-based splitting React.lazy + Suspense
Dynamic import Heavy charts, editors on demand
Tree shaking ESM imports, analyze bundle
RSC Less client JS for static regions

Measure with webpack/vite analyzer before micro-optimizing hooks.

A strong answer is:

I split by route and heavy widgets first—lazy charts and admin pages—then analyze bundle; memoization is not a substitute for code splitting.

Why does Strict Mode double-invoke effects in development?

React 18+ Strict Mode mounts, unmounts, and re-mounts components in dev to surface non-idempotent effects—duplicate subscriptions, missing cleanup.

Production: effects run once. Dev double-invoke trains resilient useEffect with proper cleanup.

A strong answer is:

Strict Mode double effects in dev expose missing cleanup—I write idempotent effects with teardown, not hacks to disable Strict Mode.

What is hydration and what causes hydration mismatches?

Hydration attaches client React to server-rendered HTML. Mismatch when server HTML ≠ client first render—causes warnings and broken UI.

Common causes: Date.now(), Math.random(), browser-only APIs in SSR, invalid HTML nesting.

A strong answer is:

Hydration requires server and client first paint to match—I gate browser-only values behind useEffect or suppress only when truly unavoidable with clear comments.


Scenario-based interview questions on React JS for experienced

Scenario: A page freezes — useEffect runs in an infinite loop. How do you debug?

Symptoms: Browser tab hangs; Network tab shows repeated identical requests.

Common cause Fix
setState in effect without deps guard Add deps or derive in render
[obj] dep — new object each render Depend on primitives or useMemo
Effect sets state that retriggers effect Remove redundant state

Walkthrough: Open component → find useEffect → check dependency array → check if setState inside always runs → move derivation to render or narrow deps.

A strong answer is:

I find the effect writing state that retriggers itself—fix deps, use functional updates, or compute during render instead of syncing state in an effect.

Scenario: Search box hammers the API on every keystroke. Fix it.

Diagnosis: No debounce; possibly no request cancellation.

Fix stack:

  1. Debounce input 300–400 ms (useDebounce custom hook)
  2. AbortController in effect cleanup
  3. useTransition if filtering large local lists
  4. TanStack Query with enabled: debouncedQuery.length > 0
javascript
function debounce(fn, ms) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), ms);
  };
}
let calls = 0;
const search = debounce(() => { calls += 1; }, 100);
search(); search(); search();
setTimeout(() => console.log(calls), 150);
Output

After ~150 ms, calls is 1—only the trailing keystroke fired.

A strong answer is:

Debounce the query, abort stale fetches, show loading state—or use Query with debounced key; I'd never fire raw onChange directly to the API.

Scenario: Memoized child still re-renders when parent updates. Why?

Checklist:

Check Issue
Props are objects/functions recreated each render Unstable reference
React.memo on child but inline onClick={() => ...} New function every render
Context parent re-renders Consumer re-renders unless split context
Child not actually memoized Missing memo

Fix: useCallback/useMemo only after profiling, move state down, split context, or pass primitive props.

A strong answer is:

Unstable callback or object props break memo—I stabilize with useCallback when profiling proves it, or colocate state so the child isn't under a hot parent.

Scenario: Dashboard with charts and tables is slow. Your investigation plan?
Step Action
1 React Profiler — which components render often?
2 Network — waterfall, overfetch, missing pagination?
3 Lists — virtualization for 1000+ rows?
4 Charts — dynamic import heavy libs?
5 State — context at root updating frequently?
6 Metrics — INP, LCP from field data

Prioritize user-visible wins before hook micro-optimization.

A strong answer is:

Profiler plus network first—I fix overfetch and unvirtualized lists before sprinkling useMemo; verify with Core Web Vitals, not gut feel.

Scenario: Design auth state for a React SPA with protected routes.

Approach:

  • Auth context or lightweight store with { user, status: 'loading' | 'authenticated' | 'anonymous' }
  • Bootstrap — single /me fetch on app load; avoid flash of wrong route
  • Protected route — render skeleton while loading; redirect only when status known
  • Token storage — httpOnly cookies preferred over localStorage for XSS resistance
  • Refresh — silent refresh or redirect to login on 401

Mention coordination with full stack API auth patterns.

A strong answer is:

Loading gate before redirect, single source of auth truth, httpOnly cookies when backend allows—I never redirect unauthenticated users before bootstrap finishes.

Scenario: Multi-step form with validation — how do you structure state?

Options:

Approach When
Single object + useReducer Medium wizard, clear actions
React Hook Form + Zod Many fields, schema validation
URL step param Shareable step, back button

Keep one source of truth; validate per step; persist draft to sessionStorage if UX requires.

A strong answer is:

useReducer or RHF with schema validation—one state machine for steps, persist optional draft, disable Next until step valid.

Scenario: Migrate class components to hooks in a legacy codebase. Strategy?
Phase Action
1 Lint rules block new class components
2 Leaf components first—low risk
3 Replace lifecycle with useEffect mapping chart
4 Extract custom hooks from repeated logic
5 Tests before refactor—RTL behavior tests

Do not big-bang rewrite—strangle by route or feature flag.

A strong answer is:

Leaf-first migration with tests locked—map componentDidMount to useEffect with cleanup, extract hooks from duplicated logic, no freeze for a six-month rewrite.

Scenario: Take-home React app — what do senior reviewers evaluate?
Area Signal
README Trade-offs, what you'd do with more time
State Clear boundaries, no prop drilling mess
Data Loading/error/empty states
Tests Critical paths covered
A11y Labels, focus, keyboard
Structure Feature folders, not 2000-line App

Over-engineering Redux for three fields scores poorly.

A strong answer is:

I ship clear README trade-offs, loading/error paths, a few meaningful tests, and accessible forms—polish on architecture judgment, not animation libraries on day one.


Final prep checklist

What should you rehearse before interview questions on React JS?

Checklist:

  • Basic — props, state, keys, controlled inputs
  • Hooks — effect deps, cleanup, stale closure fix
  • Experienced — RSC vs client, Query vs useEffect
  • React 19 — Actions, useOptimistic, compiler awareness
  • Scenarios — infinite loop, debounced search, slow dashboard
  • Timed todo and search coding reps
  • React interview questions and answers companion drills
  • Front end fundamentals
  • Full stack integration if end-to-end role

A strong answer is:

I rehearse basics aloud even for senior loops, then three scenario stories with metrics—loop fix, debounced search, dashboard profile—and one timed coding exercise per day the week before.


Pattern cheat sheet (quick reference)

Need React approach
Basic list Stable key={item.id}
Form input Controlled value + onChange
Side effect useEffect + deps + cleanup
Expensive child Profile first; then memo / stable props
Server data TanStack Query
Slow typing + filter useTransition or debounce
Global theme/locale Context (split if needed)
Render error fallback Error boundary
Less client JS RSC + route code splitting
Form mutation (React 19) Actions + useActionState

References

React documentation and interview prep

On-site prep


Summary

Experienced React interviews combine fundamentals with production judgment: infinite-loop debugging, debounced search, dashboard performance, and architecture choices you can defend aloud. Pair with React interview questions and answers for more coding drills and front end interviews for browser-wide context.

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …