35 questions · Updated
React Interview Questions and Answers
React interviews have shifted. Questions about class lifecycle methods have mostly given way to hooks, rendering behaviour and, since React 19, Server Components, Actions and the use() API. Interviewers want to know whether you understand why a component re-renders, how state updates are batched, what a dependency array really does, and when memoisation helps rather than hurts. This page collects 35 React JS interview questions and answers, from beginner concepts like JSX, props and keys through intermediate hooks questions to advanced topics such as reconciliation, concurrent rendering, Suspense, the React Compiler and the server/client boundary. The final section covers the React coding interview tasks that come up most: a custom hook, a debounced search input, a controlled form and fetching data without race conditions. Every answer reflects React 19 behaviour, and code samples use function components only. Try answering each question aloud before opening it, then revise with the React hooks cheat sheet. If the role uses Next.js, read the Server Components questions twice.
Beginner React interview questions
1.What is React and why use it?
React is a JavaScript library for building user interfaces from components. You describe what the UI should look like for a given state, and React updates the DOM to match when state changes. Its strengths are a component model that composes well, one-way data flow that makes changes predictable, and a large ecosystem. Frameworks such as Next.js and React Router add routing, data loading and server rendering on top.
2.What is JSX?
JSX is a syntax extension that lets you write markup-like code in JavaScript. A compiler turns it into function calls (the automatic runtime emits jsx() calls from react/jsx-runtime) that create React elements, which are plain objects describing the UI. JSX expressions go inside curly braces, attributes use camelCase such as className and onClick, and a component must return a single root element or a fragment.
3.What is the difference between props and state?
Props are inputs passed from a parent and are read-only inside the component. State is data a component owns and changes over time with a setter such as the one returned by useState; updating it schedules a re-render. If a value can be computed from props or other state, it should not be stored as state at all — derive it during render.
4.Why do lists need keys?
Keys tell React which item is which between renders, so it can move, insert or remove DOM nodes and preserve each item's state correctly. Keys must be stable and unique among siblings, typically a database ID. Using the array index breaks when items are reordered, inserted or removed, because state and focus can end up attached to the wrong item.
{todos.map((todo) => <TodoItem key={todo.id} todo={todo} />)}5.What are controlled and uncontrolled components?
A controlled input gets its value from React state and updates it via onChange, so React is the single source of truth. An uncontrolled input keeps its own value in the DOM, and you read it with a ref or from FormData on submit. Controlled inputs suit live validation and dependent fields; uncontrolled inputs are simpler and pair well with React 19 form Actions.
6.What does useState return, and how do updater functions work?
useState returns the current value and a setter. Calling the setter schedules a re-render with the new value; it does not change the variable in the current render. When the next value depends on the previous one, pass an updater function such as setCount(c => c + 1), so multiple updates in the same event apply in order instead of all reading the same stale value.
function handleClick() {
setCount((c) => c + 1);
setCount((c) => c + 1); // count increases by 2
}7.What is the virtual DOM?
The virtual DOM is React's in-memory tree of elements describing the UI. On each render React builds a new tree, compares it to the previous one (reconciliation) and applies only the necessary changes to the real DOM. The benefit is less a raw speed win than a programming model: you write UI as a function of state and React works out the minimal updates.
8.What is a React fragment?
A fragment groups multiple children without adding an extra DOM element. You write it as <>...</> or <Fragment>...</Fragment>; the long form is needed when you must pass a key, such as when mapping a list to pairs of elements. Fragments keep markup valid in places like tables and avoid unnecessary wrapper divs.
9.How do you render content conditionally?
Use ordinary JavaScript: an if statement with early return, the ternary operator, or the && operator. Be careful with && when the left side can be 0, because React renders 0; use a boolean like items.length > 0 instead. Returning null from a component renders nothing.
10.How does data flow between components?
Data flows down through props. A child communicates upward by calling a callback prop passed by its parent. When siblings need the same data, lift the state up to their closest common parent. For values needed by many components at different depths, use context, and for complex shared client state consider a store library.
Intermediate React interview questions (hooks)
React hooks interview questions and rendering behaviour.
11.How does useEffect work and what is the dependency array for?
useEffect runs a function after React commits a render to the screen, to synchronise with something outside React such as a subscription, timer or non-React widget. The dependency array lists reactive values the effect uses; React re-runs the effect when any of them change. An empty array runs it after the first mount only, and omitting the array runs it after every render. The function you return is the cleanup, which runs before the effect re-runs and on unmount.
useEffect(() => {
const id = setInterval(tick, 1000);
return () => clearInterval(id); // cleanup
}, [tick]);12.When should you NOT use useEffect?
Do not use an effect to compute values from props or state — calculate them during render. Do not use one to respond to a user event; put that logic in the event handler. Do not use one to reset state when a prop changes; give the component a key instead. Effects are for synchronising with external systems, and needless effects cause extra renders and bugs.
13.Why does React run effects twice in development?
In Strict Mode during development, React mounts, unmounts and re-mounts components once to surface effects that are missing cleanup. If your effect breaks when run twice, it would also break when a user navigates away and back. This does not happen in production builds.
14.What is the difference between useMemo and useCallback?
useMemo caches the result of a calculation between renders, recalculating only when its dependencies change. useCallback caches a function definition, which is equivalent to useMemo(() => fn, deps). Both matter mainly when passing values to memoised children or to other hooks' dependency arrays. With the React Compiler enabled, much of this manual memoisation is done automatically.
15.What is useRef used for?
useRef returns a mutable object whose current property persists across renders without causing a re-render when it changes. It is used to hold DOM nodes, timer IDs, previous values and other instance-like data. Do not read or write ref.current during rendering for values that affect output; that is what state is for. In React 19, function components can receive ref as a regular prop, so forwardRef is no longer needed.
16.When would you choose useReducer over useState?
useReducer suits state with several related fields or many update types, because all transitions live in one pure reducer function that is easy to test. You dispatch actions describing what happened rather than setting values directly. For a single boolean or string, useState is simpler.
17.How does the Context API work and what are its drawbacks?
createContext creates a context; a provider supplies a value to everything below it, and components read it with useContext or, in React 19, use(). It avoids passing props through many layers. The drawback is that every consumer re-renders when the provider's value changes, so put fast-changing values in separate contexts and memoise object values. Context is a transport mechanism, not a full state manager.
18.What are the rules of hooks?
Call hooks only at the top level of a component or custom hook, never inside conditions, loops or nested functions, so they run in the same order every render. Call them only from React function components or custom hooks. React relies on call order to match each hook with its stored state. The use() API is the one exception: it can be called conditionally.
19.What is a custom hook?
A custom hook is a function whose name starts with use and which calls other hooks, letting you share stateful logic between components. Each component that calls it gets its own independent state. Typical examples are useDebounce, useMediaQuery or a data-fetching hook. Custom hooks share logic, not state.
20.What causes a component to re-render?
A component re-renders when its own state changes, when its parent re-renders, or when a context it reads changes. Re-rendering is not the same as updating the DOM: React only touches the DOM if the output differs. React.memo lets a component skip re-rendering when its props are shallowly equal to the previous ones.
21.What does React.memo do and when is it worth using?
React.memo wraps a component so it skips re-rendering when its props are shallowly equal to last time. It helps when a component renders often with the same props and is expensive to render. It is useless if you pass new object, array or function props on every render, which is why it is often paired with useMemo and useCallback — or replaced entirely by the React Compiler.
22.What are error boundaries?
Error boundaries catch errors thrown while rendering their children and show a fallback UI instead of unmounting the whole tree. They are still written as class components using getDerivedStateFromError and componentDidCatch, or via a library like react-error-boundary. They do not catch errors in event handlers, async code or server-side rendering; handle those with try/catch.
Advanced React interview questions
React 19, concurrency, Server Components and performance.
23.What are React Server Components?
Server Components render ahead of time on the server (at build time or per request) and send their output to the client, so their code and dependencies never ship in the JavaScript bundle. They can be async and read data directly from a database or file system. They cannot use state, effects or browser APIs. Client Components are marked with the "use client" directive at the top of a module and handle interactivity; Server Components can render Client Components and pass them serialisable props.
// Server Component (default in Next.js App Router)
export default async function Posts() {
const posts = await db.post.findMany();
return <PostList posts={posts} />; // PostList may be a Client Component
}24.What is the use() API in React 19?
use() reads the value of a promise or a context during render. With a promise, the component suspends until it resolves, showing the nearest Suspense fallback, and a rejection goes to the nearest error boundary. Unlike other hooks, use() can be called inside conditions and loops. Promises passed to it should be created outside the render (for example in a Server Component or cached), not recreated on every render.
"use client";
import { use } from "react";
function Comments({ commentsPromise }) {
const comments = use(commentsPromise);
return comments.map((c) => <p key={c.id}>{c.text}</p>);
}25.What are Actions, useActionState and useFormStatus?
In React 19 an Action is an async function used in a transition, commonly passed to a form's action prop. React manages pending state, errors and form reset for you. useActionState wraps an action and returns the latest result, a wrapped action and an isPending flag. useFormStatus lets a child component, such as a submit button, read whether its parent form is submitting. With Server Functions ("use server"), the action can run on the server.
const [error, submitAction, isPending] = useActionState(
async (prev, formData) => {
const res = await updateName(formData.get("name"));
return res.error ?? null;
},
null
);
// <form action={submitAction}>...</form>26.What does useOptimistic do?
useOptimistic shows a temporary, optimistic version of state while an async action is in progress, for example displaying a new message before the server confirms it. You provide the real state and an update function; when the action finishes, React switches back to the real state, so a failure automatically reverts the optimistic change.
27.Explain reconciliation and the diffing heuristics.
When state changes, React compares the new element tree with the previous one. Elements of a different type at the same position are torn down and rebuilt, including their state. Elements of the same type are updated in place, keeping state. Children lists are matched by key. These heuristics make diffing roughly linear instead of the cubic cost of a general tree diff, and they explain why changing a key resets a component.
28.What is concurrent rendering and what do useTransition and useDeferredValue do?
Concurrent rendering lets React prepare a render in the background and interrupt it when something more urgent, like typing, happens. useTransition marks a state update as non-urgent and gives you an isPending flag, so the UI stays responsive during expensive updates. useDeferredValue gives you a lagging copy of a value, letting an expensive child re-render with the old value until React has time for the new one.
29.How does Suspense work?
Suspense lets you declare a fallback UI for a part of the tree that is not ready yet. A child suspends while lazy-loaded code or data (via use() or a Suspense-enabled framework) is loading, and React shows the closest Suspense boundary's fallback. On the server, Suspense enables streaming HTML: the shell is sent first and suspended sections stream in as they resolve.
30.What is the React Compiler?
The React Compiler is a build-time tool that automatically memoises components and values, so you rarely need useMemo, useCallback or React.memo by hand. It relies on your code following the rules of React — pure render functions and no mutation of props or state. It reached its stable 1.0 release in 2025 and can be adopted incrementally through a Babel plugin or framework integration.
31.What is hydration and what causes hydration mismatches?
Hydration is the process where React attaches event handlers and state to HTML that was rendered on the server, instead of rebuilding the DOM. A mismatch happens when the first client render produces different output from the server, for example by using Date.now(), Math.random(), window checks or locale-dependent formatting during render. Fix it by rendering stable output first and updating in an effect, or by using suppressHydrationWarning for unavoidable cases like timestamps.
React coding interview questions
32.Write a useDebounce custom hook.
Store the debounced value in state, and in an effect start a timer that updates it after the delay. The cleanup clears the timer whenever the value changes, so only the last value within the window is committed.
function useDebounce(value, delay = 300) {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const id = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(id);
}, [value, delay]);
return debounced;
}33.Fetch data in an effect without race conditions.
If the input changes quickly, an older request can resolve after a newer one and overwrite the result. Use an AbortController (or an ignore flag) in the cleanup so stale responses are discarded. In production, prefer a framework loader, Server Components or a library like TanStack Query, which handle caching and deduplication.
useEffect(() => {
const controller = new AbortController();
fetch("/api/users?q=" + encodeURIComponent(query), { signal: controller.signal })
.then((r) => r.json())
.then(setUsers)
.catch((e) => { if (e.name !== "AbortError") setError(e); });
return () => controller.abort();
}, [query]);34.Build a counter that cannot go below zero.
Use the updater form so rapid clicks are computed from the latest state, and clamp the value. Disabling the button at zero improves the UX, but the clamp keeps the state valid regardless.
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount((c) => Math.max(0, c - 1))} disabled={count === 0}>-</button>
<span>{count}</span>
<button onClick={() => setCount((c) => c + 1)}>+</button>
</div>
);
}35.Implement a filterable list.
Keep only the query in state and derive the filtered list during render; do not store the filtered array in state or sync it with an effect. For large lists, wrap the filtering in useMemo or defer the query with useDeferredValue.
function FilterableList({ items }) {
const [query, setQuery] = useState("");
const visible = items.filter((i) =>
i.name.toLowerCase().includes(query.toLowerCase())
);
return (
<>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
<ul>{visible.map((i) => <li key={i.id}>{i.name}</li>)}</ul>
</>
);
}Preparing for a React interview
Common questions about getting ready
How do I prepare for a React interview in 2026?
Make sure you can explain rendering and re-rendering, the main hooks (useState, useEffect, useRef, useMemo, useCallback, useContext, useReducer), keys and reconciliation. Then learn the React 19 additions: Server Components, use(), Actions with useActionState and useOptimistic. Finally, build two or three small components from scratch under time pressure, such as a debounced search or a todo list.
Do interviewers still ask about class components?
Occasionally, mainly in companies with older codebases. Knowing that class lifecycle methods map roughly to effects, and that error boundaries are still classes, is usually enough. New code is written with function components and hooks.
Are React hooks interview questions the most common?
Yes. Most React interview questions revolve around hooks: dependency arrays, stale closures, cleanup, when to avoid effects and when memoisation helps. Expect at least one follow-up on why a component re-rendered or why an effect ran more than expected.
Should I learn Next.js for a React interview?
If the job description mentions Next.js or server rendering, yes. Server Components, Server Functions, streaming and caching are framework-level concepts that are easiest to discuss with Next.js experience. For a client-only React role, focus on hooks and state management first.
What React coding challenges are common?
Typical tasks include a counter or todo list, a debounced search input, fetching and displaying data with loading and error states, a modal or tabs component, pagination, and a custom hook. Interviewers watch for derived state, correct keys, effect cleanup and accessible markup.

