Interview Bank · 2026

⚛️ React

Components, hooks, the virtual DOM, and the gotchas that separate "I've used React" from "I think in React." Say each answer aloud before you reveal it.

Rapid-fire flashcards flip to check

Click a card. Answer first, in one breath, then reveal.

What is a component?
A reusable function that takes props and returns UI (JSX). The building block of a React app.
click to flip
Props vs state?
Props are passed in from the parent and read-only; state is owned by the component and changes over time, triggering re-renders.
click to flip
What does useState do?
Adds local state to a function component — returns the current value and a setter that re-renders on change.
click to flip
What does useEffect do?
Runs side effects (fetching, subscriptions, timers) after render, controlled by a dependency array.
click to flip
What is the key prop?
A stable, unique id on list items so React can track which item is which across re-renders.
click to flip
What is a controlled input?
An input whose value is driven by React state — value={x} plus an onChange that updates it.
click to flip
What is the virtual DOM?
An in-memory tree of the UI; React diffs the new tree against the old and patches only what changed in the real DOM.
click to flip
What is JSX?
HTML-like syntax that compiles to React.createElement calls — markup and logic in one place.
click to flip
The Rules of Hooks?
Only call hooks at the top level (no conditions/loops) and only from React functions — so call order stays stable.
click to flip
useMemo vs useCallback?
useMemo caches a computed value; useCallback caches a function reference. Both skip work when deps are unchanged.
click to flip

Core questions

How does a state change trigger a re-render?

Calling a state setter (e.g. setCount) tells React the component is "dirty." React re-runs the component function to produce a new virtual-DOM tree, diffs it against the previous one, and applies the minimal set of changes to the real DOM. You never touch the DOM yourself — you change state and describe the result.

Explain useEffect and its dependency array (and cleanup).

The effect runs after render. The dependency array controls when: [] = once on mount; [a, b] = whenever a or b changes; omitted = after every render. Returning a function gives you cleanup — React runs it before the next effect and on unmount (unsubscribe, clear a timer, abort a fetch). List every value the effect reads, or you'll get stale data.

What does "lifting state up" mean?

When two siblings need the same data, you move that state to their nearest common parent and pass it down as props (plus a callback to update it). The parent becomes the single source of truth. It's the standard fix for "these two components must stay in sync."

Controlled vs uncontrolled inputs?

Controlled: React state holds the value (value + onChange) — you can validate, transform, and reset easily. Uncontrolled: the DOM holds the value and you read it with a ref when needed. Controlled is the default recommendation; uncontrolled is handy for simple or third-party-managed fields.

How do keys affect reconciliation?

During diffing, keys tell React which list item is the same across renders. With good keys React moves/updates existing nodes; with bad keys it tears down and rebuilds, losing focus and state and slowing things down. Keys must be stable and unique — use an id from your data, not the array index.

What is useContext for?

It reads a value from a Context.Provider higher in the tree without passing props through every level ("prop drilling"). Good for app-wide things: theme, current user, auth. Note any consumer re-renders when the context value changes, so keep volatile state out of broad contexts.

What is a custom hook, and why write one?

A function starting with use that calls other hooks to package reusable stateful logic — e.g. useFetch, useDebounce. It shares behaviour, not markup, and keeps components lean. It's the React equivalent of the reusable jQuery plugins you used to write — logic you drop into many places.

useRef vs state?

useRef holds a mutable value that persists across renders but does not trigger one when it changes — for DOM nodes, timer ids, or "previous value" bookkeeping. State is for values that should re-render the UI. Rule of thumb: if changing it should update what the user sees, use state; otherwise a ref.

Theory deep-cuts the "why"

How do the virtual DOM and reconciliation work? theory

React keeps a lightweight in-memory representation of the UI. On a state change it builds a new tree and runs reconciliation — a diff against the old tree. It assumes elements of the same type are the same, recurses into children, and computes the minimal DOM operations to apply. This batched, targeted patching is why you rarely touch the DOM directly.

Why do keys matter for the diff? theory

Without keys, React diffs list children by position, so inserting at the top makes it think every item changed. Keys give each item an identity, so React can match "item 7 is still item 7" and just reorder or update it — preserving its DOM node, focus, and internal state. They are the hint that makes list diffing correct and fast.

Declarative vs imperative (vs jQuery)? theory

In jQuery you wrote imperative steps: "find this node, toggle that class, append a row." In React you write declarative UI: "given this state, here's what the screen should look like," and React figures out the DOM mutations. You describe the destination, not the turn-by-turn directions — fewer bugs from the DOM drifting out of sync with your data.

What is one-way data flow? theory

Data flows down the tree via props; events flow up via callbacks. A child can't reach up and mutate its parent's state — it calls a function the parent gave it. This single direction makes the app predictable: to find why something changed, you trace upward to where the state lives.

Why must hooks run unconditionally at the top level? theory

React tracks hooks by call order, not by name — the first useState is "slot 1" every render. If you put a hook inside an if or a loop, the order can change between renders and React maps your state to the wrong slot. Calling them unconditionally at the top keeps the order stable, which is the whole reason the Rules of Hooks exist.

Derived state vs storing duplicate state? theory

If a value can be computed from existing props/state, compute it during render instead of storing it in its own useState. Duplicating it means two sources of truth that drift out of sync (you update one and forget the other). Keep the minimal state; derive the rest. useMemo only if the computation is genuinely expensive.

Tricky & gotchas where candidates trip

What is a stale closure inside useEffect? tricky

An effect "captures" the variables from the render it ran in. If you set up a one-time effect ([]) that reads count, it forever sees the first count, even as state updates. Fix: add the value to the deps so the effect re-subscribes, or use the functional setter setCount(c => c + 1) which never needs the current value.

How does a missing dependency cause a stale value or an infinite loop? tricky

Omit a dependency and the effect keeps using an old value (stale). But add one carelessly — like a function or object recreated every render, or a value the effect itself updates — and the effect re-runs every render, looping forever. Fix the loop by memoising the dependency (useCallback/useMemo) or restructuring so the effect doesn't set the very state it depends on.

Why is key={index} an antipattern? tricky

When the list reorders, inserts, or deletes, indexes shift, so React matches the wrong items — causing wrong content, lost input focus, and checkbox state landing on the wrong row. Indexes are only safe for a static, append-only list. Use a stable id from the data instead.

Can you call a hook conditionally or in a loop? tricky

No. if (x) useState() or a hook inside a for breaks the call-order contract React relies on, and the linter/runtime will error. Put the condition inside the hook instead (e.g. useEffect(() => { if (x) {...} })), or split into separate components.

Why is setState asynchronous / batched? tricky

Setters schedule an update; they don't mutate immediately, and React batches multiple updates into one re-render for performance. So reading state right after setting it gives the old value, and setCount(count+1) twice only adds one. Use the functional form setCount(c => c + 1) when the next value depends on the previous.

Why does useEffect run twice in StrictMode? tricky

In development only, StrictMode intentionally mounts, unmounts, and remounts components to surface effects that aren't cleaned up properly. It does not happen in production. The fix is almost always to return a proper cleanup function — not to disable StrictMode.

What's new in 2026 say this and stand out

What landed in React 19? 2026

Actions plus useActionState streamline form submission, pending states, and errors; useOptimistic shows an instant optimistic UI while a mutation is in flight; the new use() hook reads a promise or context (and can be called conditionally, unlike other hooks); and ref is now a normal prop — no more forwardRef boilerplate. Mentioning these signals you're current.

What is the React Compiler? 2026

An optimising compiler that auto-memoises components and values at build time, so React skips re-rendering and recomputing things that didn't change — without you hand-writing useMemo/useCallback/memo everywhere. It reduces a whole category of manual performance work; you still understand those hooks, but lean on them far less.

Where do Server Components fit? 2026

React Server Components are now a first-class concept: components that render on the server, ship zero JS for themselves, and can fetch data directly — reducing bundle size and round-trips. You meet them mainly through a framework, so the deep dive lives in the Next.js bank; here, just know what they are and why they exist.

Memory hooks UI = f(state). The screen is a function of your state — change state, React redraws the rest.
Keys = name tags. They let React track which list item is which across renders.
Hooks at the top, every time. No if, no loop — React counts them by order.
Tie it to DocChat When asked "do you know React?", don't recite — point: "DocChat's frontend is React — a controlled chat input, useEffect to stream answers, custom useFetch hook, and keys on the message list." Concrete beats abstract.