52 questions - Beginner to advanced

React interview questions and answers

React interviews focus on three things: how state and props flow, what makes a component re-render, and whether you understand hooks well enough to avoid bugs. Answer with the "why", not just the API name.

React fundamentals

What is React?

React is a JavaScript library for building user interfaces out of components. You describe what the screen should look like for a given state, and React works out the smallest set of DOM changes needed to get there.

What is JSX?

JSX is HTML-like syntax written inside JavaScript. A build tool converts each tag into a function call, so JSX is only a nicer way to describe elements. Because it becomes JavaScript, you use className instead of class and camelCase event names.

const el = <h1 className="title">Hello</h1>;
// becomes roughly:
// jsx("h1", { className: "title", children: "Hello" })

What is the virtual DOM?

A lightweight copy of the UI kept in memory. When state changes, React builds a new copy, compares it with the old one, and applies only the differences to the real DOM. Touching the real DOM is slow, so this saves work.

What is reconciliation?

The process of comparing the new element tree with the previous one. React assumes that different element types produce different trees, so it throws away the old subtree, and it uses keys to match children in a list.

What is the difference between props and state?

Props come from the parent, are read-only inside the component, and changing them is the parent job. State belongs to the component, is private, and changing it with the setter triggers a re-render.

Why must you not modify state directly?

React compares the old and new state by reference. If you mutate the same object, the reference does not change and React sees nothing new, so the screen does not update. Always create a new object or array.

// wrong
items.push(newItem);
setItems(items);

// right
setItems([...items, newItem]);

What are keys in a list and why do they matter?

A key tells React which item is which between renders, so it can move DOM nodes instead of rebuilding them. Use a stable unique id. Using the array index breaks when items are inserted, removed or reordered - inputs keep the wrong values and animations jump.

What is a controlled component?

A form input whose value comes from React state and whose changes go back through onChange. React is the single source of truth. An uncontrolled input keeps its value in the DOM and you read it with a ref, which is simpler but harder to validate live.

const [name, setName] = useState("");
<input value={name} onChange={(e) => setName(e.target.value)} />

What is a fragment?

A wrapper that groups several elements without adding a real DOM node. Written as <>...</> or <React.Fragment>. Use the long form when you need a key, for example inside a list.

What is the difference between a class component and a function component?

Class components use lifecycle methods and this.state. Function components are plain functions that use hooks. Function components are the standard today: less code, no this confusion, and logic is easier to share.

What is conditional rendering?

Deciding what to render with normal JavaScript - a ternary, && or an early return. Be careful with && and numbers: 0 && <X/> renders 0 on the screen, so compare explicitly.

{items.length > 0 && <List items={items} />}   // safe
{items.length && <List items={items} />}       // renders 0 when empty

What is prop drilling?

Passing a prop through several components that do not need it, only to reach a deep child. Fix it with Context, composition (passing children), or a state library - but not by reaching for Context for every value.

Hooks

The heart of a modern React interview.

What are the rules of hooks?

Call hooks only at the top level of a component or another hook - never inside an if, a loop or a nested function - and only from React functions. React matches hooks to state by call order, so a conditional hook shifts everything.

How does useState work?

It returns the current value and a setter. Calling the setter schedules a re-render. When the new value depends on the old one, pass a function so you always read the latest value.

const [count, setCount] = useState(0);
setCount((c) => c + 1); // safe inside async code and batches

What is lazy initial state?

Passing a function to useState so the expensive calculation runs only on the first render instead of every render.

const [rows, setRows] = useState(() => parseBigJson(raw));

What does useEffect do?

It runs side effects after the render is painted - data fetching, subscriptions, timers, manual DOM work. The dependency array decides when it runs again, and the returned function cleans up before the next run and on unmount.

useEffect(() => {
  const id = setInterval(tick, 1000);
  return () => clearInterval(id);
}, []);

What is the difference between an empty array, no array and a filled array in useEffect?

No array means it runs after every render. An empty array means once after the first render. An array with values means it runs again whenever one of those values changes.

What is the most common useEffect mistake?

Missing dependencies, which makes the effect read stale values, and forgetting cleanup, which leaks timers and listeners. A close second is using an effect to derive state that could just be calculated during render.

What is the difference between useEffect and useLayoutEffect?

useEffect runs after the browser has painted, so it does not block the screen. useLayoutEffect runs synchronously after the DOM update but before paint, which is right when you must measure an element and adjust it without the user seeing a flicker.

What is useRef used for?

Two things: holding a reference to a DOM node, and keeping a mutable value between renders that does not cause a re-render when it changes - like a timer id or a previous value.

const inputRef = useRef(null);
useEffect(() => inputRef.current?.focus(), []);
<input ref={inputRef} />

What is the difference between useRef and useState?

Changing state re-renders the component; changing a ref does not. Use state for anything the UI shows, and a ref for values you only read in handlers and effects.

What is useMemo?

It caches the result of an expensive calculation and only recalculates when a dependency changes. It is also used to keep an object or array reference stable so a memoised child does not re-render.

const sorted = useMemo(
  () => [...items].sort((a, b) => a.price - b.price),
  [items]
);

What is useCallback?

It returns the same function reference between renders as long as the dependencies are unchanged. It only helps when the function is passed to a memoised child or used as an effect dependency.

When should you not use useMemo or useCallback?

When the work is cheap. They are not free - they cost memory and comparison on every render, and they make the code noisier. Measure first, then optimise.

What is useReducer and when is it better than useState?

useReducer keeps state in one place and updates it through actions. It is better when several values change together, when the next state depends heavily on the previous one, or when the update logic is complex enough to test on its own.

function reducer(state, action) {
  switch (action.type) {
    case "add": return { ...state, count: state.count + 1 };
    default: return state;
  }
}
const [state, dispatch] = useReducer(reducer, { count: 0 });

What is useContext?

It reads a value from the nearest Provider above it, so you can share data without prop drilling. Every consumer re-renders when the provider value changes, so split contexts and memoise the value object.

const ThemeContext = createContext("light");

function Button() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>Save</button>;
}

Is Context a replacement for Redux?

No. Context is a way to pass a value down the tree; it has no reducers, no devtools, no middleware and no selective subscriptions. It suits theme, locale and the current user. Frequently changing global data is better in a state library.

What is a custom hook?

A function starting with "use" that calls other hooks. It lets you reuse logic - not markup - between components. Each component that calls it gets its own separate state.

function useDebounced(value, delay = 300) {
  const [debounced, setDebounced] = useState(value);
  useEffect(() => {
    const id = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(id);
  }, [value, delay]);
  return debounced;
}

What is useId for?

It generates a stable unique id that matches between the server and the client, which is the correct way to connect a label to an input in a reusable component without clashing ids.

What do useTransition and useDeferredValue do?

They mark an update as low priority so React can keep the interface responsive. useTransition wraps a state update; useDeferredValue keeps showing the old value while an expensive re-render happens in the background. Both help with heavy filtered lists.

Rendering and performance

What causes a component to re-render?

Its own state changed, a context it consumes changed, or its parent re-rendered. Note that props changing is not a separate reason - props change because the parent re-rendered.

What does React.memo do?

It skips re-rendering a component when its props are shallowly equal to last time. It does nothing if you pass a new object, array or inline function on every render, which is why it pairs with useMemo and useCallback.

What is batching in React?

React groups several state updates into one re-render. Since React 18 this happens everywhere, including inside promises and timers, not just in event handlers.

How do you fix a slow long list?

Virtualise it, so only the visible rows exist in the DOM, using a library like react-window. Also memoise the row component and give it stable props and keys.

What is code splitting in React?

Loading part of the JavaScript only when it is needed, with React.lazy and Suspense, usually per route. It reduces the size of the first download.

const Dashboard = lazy(() => import("./Dashboard"));

<Suspense fallback={<Spinner />}>
  <Dashboard />
</Suspense>

What is an Error Boundary?

A component that catches a JavaScript error thrown while rendering its children and shows a fallback instead of a blank page. It must be a class component today, and it does not catch errors in event handlers or async code.

What is Strict Mode and why do effects run twice?

In development, Strict Mode mounts a component, unmounts it and mounts it again to reveal missing cleanup. It only happens in development. If double running breaks something, your effect is missing a cleanup function.

What is a portal?

It renders a child into a different part of the DOM, usually document.body, while keeping it in the React tree - so context and events still work. It is the standard solution for modals and tooltips that must escape an overflow: hidden parent.

createPortal(<Modal />, document.body);

What is the difference between CSR, SSR and SSG?

Client-side rendering sends an empty page and builds it in the browser. Server-side rendering builds the HTML per request, so the first paint and SEO are better. Static site generation builds the HTML once at build time, which is fastest but only suits content that does not change per user.

What is hydration?

The client React attaching event handlers to server-rendered HTML. If the markup the client produces does not match the server, you get a hydration mismatch warning - usually caused by using dates, random values or window during render.

What are Server Components?

Components that run only on the server and send their output to the client. They can query a database directly, send no JavaScript to the browser, and cannot use state or effects. They are combined with normal client components.

State, data and routing

How do you share state between two sibling components?

Lift the state up to their nearest common parent and pass the value down as a prop and the setter down as a callback. If the parent is far away, use context or a state library.

How do you fetch data in React?

In a small app, useEffect with fetch plus loading and error state, and an AbortController for cleanup. In a real app, use a data library such as React Query or SWR, which handles caching, retries, deduplication and refetching for you.

useEffect(() => {
  const c = new AbortController();
  fetch("/api/users", { signal: c.signal })
    .then((r) => r.json())
    .then(setUsers)
    .catch((e) => { if (e.name !== "AbortError") setError(e); });
  return () => c.abort();
}, []);

What is a race condition in data fetching and how do you avoid it?

The user changes the search term quickly, the first slow response arrives after the second, and the wrong results are shown. Fix it by aborting the previous request or by ignoring a response when the effect has already been cleaned up.

What is the difference between server state and client state?

Server state lives somewhere else, can become stale and needs caching and refetching - that is what React Query is for. Client state is purely local, like whether a dropdown is open. Mixing them in one store makes both harder.

How does routing work in a React SPA?

A router library maps the URL to a component and updates the URL with the history API instead of reloading. The server must send index.html for every path, otherwise a direct visit to a deep link returns a 404.

What is a protected route?

A wrapper component that checks whether the user is logged in and either renders the page or redirects to login, usually keeping the intended URL so the user comes back after signing in.

What is the children prop and composition?

children is whatever you put between the opening and closing tags of a component. Passing components as children rather than passing data down many levels is often the simplest fix for prop drilling.

What is a higher-order component?

A function that takes a component and returns a new one with extra behaviour. It was the old way to share logic; custom hooks do the same thing more clearly, so HOCs are now mostly seen in older code.

What are render props?

Passing a function as a prop so the child decides what to render with the data it provides. Like HOCs, custom hooks have largely replaced this pattern.

How do you test a React component?

With React Testing Library, render the component and interact with it the way a user would - find elements by their visible text or accessible role and assert on what the user sees. Avoid testing internal state or implementation details.

What is the difference between React and a framework like Next.js?

React is only the view library - you assemble routing, data fetching and the build yourself. Next.js is a framework built on React that adds file-based routing, server rendering, API routes and image optimisation out of the box.

Continue with another topic

Practise live

CrackInterviewAI listens to the live interview and gives a structured answer on screen for coding, system design, HR and project questions. Download for Windows.