Web Development with React
ConceptIntermediate 30 min· Project and career · 21 of 21

React interview essentials

The React questions that come up again and again in frontend interviews, with short, correct answers you can say in your own words, the classic pitfalls (stale state, missing keys, effect loops) and the small coding tasks interviewers like to set.

Frontend interviews for freshers and early-career developers are predictable. Interviewers want to know three things: do you understand how React actually works (not just copy patterns), can you write a small component live without panicking, and can you talk about something you built.

This lesson collects the core questions with answers you can adapt. Do not memorise the sentences. Read the idea, close the page, and explain it aloud using your own example. Interviewers can tell the difference, and a follow-up question ('why?') will expose memorised answers.

Round 1: the fundamentals

Core questions and short answers

QuestionA good short answer
What is React?A JavaScript library for building user interfaces from reusable components. You describe what the UI should look like for the current state, and React updates the page to match.
What is JSX?A syntax that looks like HTML inside JavaScript. Tools (Babel, or the compiler in Vite) turn it into normal JavaScript function calls. It must return one root element, uses className and htmlFor, and {} embeds JavaScript expressions.
What is the virtual DOM?A lightweight JavaScript description of the UI. When state changes React builds a new description, compares it with the previous one (diffing, also called reconciliation) and applies only the differences to the real DOM. The benefit is simpler code and efficient updates, not that it is magically faster than hand-written DOM code.
Props vs state?Props are inputs passed from a parent and are read-only for the child. State is data a component owns and can change over time; changing it causes a re-render.
Why do lists need keys?Keys let React match items between renders so it can reorder, add or remove the right elements and keep their state. Use a stable unique id. An array index is risky if the list can be reordered, filtered or inserted into.
Controlled vs uncontrolled inputs?In a controlled input, React state is the source of truth (value and onChange). In an uncontrolled input, the DOM holds the value and you read it with a ref or on submit. Controlled is the default for validation and live feedback.
What is lifting state up?When two components need the same data, move the state to their closest common parent and pass it down as props, with callbacks for updates.
What is prop drilling and how do you avoid it?Passing props through many layers that do not use them. Use composition (children), Context, or a state library for shared state.

Round 2: hooks

Hook questions

QuestionA good short answer
Rules of hooks?Call hooks only at the top level of a component or custom hook (not inside loops, conditions or nested functions), and only from React functions. React tracks hooks by their call order.
How does useEffect work?It runs after render. The dependency array controls when: no array means every render, [] means once after mount, [a, b] means when a or b changes. The returned function is cleanup and runs before the next effect and on unmount.
When should you NOT use useEffect?For things you can calculate during render (derived values) or do in an event handler. Effects are for syncing with something outside React: network, timers, subscriptions, the DOM.
useRef?A box that holds a value that persists between renders without causing a re-render when changed. Common uses: access a DOM element, store a timer id.
useMemo vs useCallback?useMemo caches a calculated value; useCallback caches a function. Both depend on a dependency array. Use them when a measured problem exists, usually together with React.memo.
useReducer vs useState?useReducer suits state with several related fields or many update types, because all transitions live in one reducer function. useState is simpler for independent values.
What is a custom hook?A function whose name starts with use and that calls other hooks, to reuse stateful logic (for example useFetch or useDebounce). Each call gets its own state.

The pitfalls interviewers love

Questions about bugs show real understanding. Learn to explain these four, with the fix.

Pitfall 1: stale state in a click handler
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  function addThree() {
    setCount(count + 1);
    setCount(count + 1);
    setCount(count + 1);
  }
  // After one click, count is 1, not 3.

  function addThreeCorrectly() {
    setCount((c) => c + 1);
    setCount((c) => c + 1);
    setCount((c) => c + 1);
  }
  // After one click, count is 3.

  return (
    <>
      <p>{count}</p>
      <button onClick={addThree}>+3 (wrong)</button>
      <button onClick={addThreeCorrectly}>+3 (right)</button>
    </>
  );
}

Why: each render has its own snapshot of count. All three calls use the same old value, so they set the same number. State updates are also batched. The functional form receives the latest value. Use it whenever the new state depends on the previous state.

Pitfall 2: mutating state
// Wrong: same array reference, React may not re-render
items.push(newItem);
setItems(items);

// Right: a new array
setItems([...items, newItem]);

// Update an object or an item inside an array without mutation
setUser({ ...user, name: 'Asha' });
setItems(items.map((i) => (i.id === id ? { ...i, qty: i.qty + 1 } : i)));
setItems(items.filter((i) => i.id !== id));

React decides whether state changed by comparing references. Treat state as read-only and always create new arrays and objects.

Pitfall 3: effects that loop or never stop
// Infinite loop: setting state in an effect with no dependency array
useEffect(() => {
  setCount(count + 1);
});

// A new object each render in the dependency list also re-runs the effect every render
const options = { page: 1 };
useEffect(() => { load(options); }, [options]);

// Fix: depend on primitive values
useEffect(() => { load({ page }); }, [page]);

// Always clean up timers and subscriptions
useEffect(() => {
  const id = setInterval(tick, 1000);
  return () => clearInterval(id);
}, []);

Explain: the effect runs after every render if there is no array, setting state causes a render, and the cycle repeats. Object and function dependencies are new every render, so they trigger the effect each time.

Pitfall 4: StrictMode runs effects twice in development. In development, <StrictMode> mounts, unmounts and re-mounts each component once to expose missing cleanup. So an effect with a fetch may run twice in npm run dev, but not in production. The right response is to write proper cleanup (an ignore flag or AbortController), not to remove StrictMode.

Round 3: architecture and performance

Broader questions

QuestionA good short answer
How do you manage state in a big app?Sort state by kind: local state in components, shared client state in Context or Zustand/Redux, server data in TanStack Query, and shareable state in the URL. Choose the simplest tool for each. (See *Managing app state*.)
Why can Context hurt performance?Every consumer re-renders when the context value changes. Keep context for rarely changing values or split it into several contexts.
How do you optimise a slow React app?Measure first with the Profiler and Lighthouse. Then code-split routes, resize images, virtualise long lists, keep state close to where it is used, debounce inputs, and memoise only the proven hot spots.
CSR vs SSR?With client-side rendering the browser builds the page after JavaScript loads. With server rendering the server sends ready HTML, which helps first load and SEO. Next.js provides it. (See *Next.js*.)
What is code splitting?Loading code in pieces on demand with React.lazy and dynamic import(), so users do not download pages they never visit.
How do you handle errors in React?Handle failed requests in state (an error state in the UI). For render errors, use an error boundary, which is a class component, or the react-error-boundary package; Next.js has error.js.
How do you make a component accessible?Use native elements, label inputs, give images alt text, support keyboard use and focus, keep enough contrast, and test with Lighthouse, axe and a keyboard.
How do you test React code?Vitest or Jest with React Testing Library: render, query by role or label, simulate user events, assert on visible output, and mock the network.

Round 4: live coding

Many companies give a 30 to 45 minute task in a browser editor, or ask you to share your screen. Common ones: a counter with reset, a todo list (add, delete, toggle), a search filter on a list, fetch and display a list from an API with loading and error states, a tabs or accordion component, a star rating, a debounced search box, a form with validation.

How to approach them:

1. Repeat the requirements and ask about edge cases (empty list? duplicate names? what if the request fails?). 2. Start simple and working. Hard-code data, get one thing on screen, then add features. 3. Think aloud. Say what state you need and why before typing. 4. Handle loading, empty and error states. Many candidates forget; interviewers notice. 5. Keep names clear and components small. Then tidy up if time remains. 6. If stuck, say what you have tried. Interviewers usually give hints and judge how you respond.

A typical task: debounced search with a fake API
import { useEffect, useState } from 'react';

const ITEMS = ['Espresso', 'Cappuccino', 'Cold Brew', 'Filter Coffee', 'Masala Chai'];

export default function Search() {
  const [query, setQuery] = useState('');
  const [debounced, setDebounced] = useState('');

  // Update the debounced value 300 ms after the user stops typing
  useEffect(() => {
    const id = setTimeout(() => setDebounced(query), 300);
    return () => clearTimeout(id);
  }, [query]);

  const results = ITEMS.filter((name) =>
    name.toLowerCase().includes(debounced.toLowerCase())
  );

  return (
    <div>
      <label htmlFor="s">Search the menu</label>
      <input id="s" value={query} onChange={(e) => setQuery(e.target.value)} />
      {results.length === 0 ? (
        <p>No matches</p>
      ) : (
        <ul>
          {results.map((name) => (
            <li key={name}>{name}</li>
          ))}
        </ul>
      )}
    </div>
  );
}

Be ready to explain: why the cleanup function exists (cancels the previous timer so only the last keystroke counts), why there are two state variables, and what you would change to call a real API (fetch inside another effect that depends on debounced).

Talking about your projects

Almost every interview includes 'tell me about a project you built'. Prepare a one-minute answer for your best project using this order: what it is and who it is for, the stack and why you chose it, one hard problem and how you solved it, what you would improve. For the recipe finder, a good 'hard problem' is the race condition between two quick searches and how an ignore flag in the effect cleanup fixed it, or storing the search in the URL so links are shareable.

Have the live link and the repository ready. Be prepared to open the code and explain any file. Never claim a project you did not build or cannot explain; follow-up questions will show it.

Answers that hurt you

1. Saying 'the virtual DOM makes React fast' without explaining diffing. 2. Claiming useMemo should be used everywhere. 3. Saying you used a library (Redux, Next.js) without being able to say why. 4. Bluffing. 'I have not used that, but here is how I would learn it' is a fine answer. 5. Not knowing what is in your own resume.

A practice plan

Two weeks before your interview

  1. Re-read the tables above and explain each answer aloud with your own example.
  2. Rebuild from scratch, without looking: a todo app, a fetch-and-list page and a debounced search.
  3. Explain stale state, state mutation and effect dependencies without notes.
  4. Revise JavaScript too: closures, this, promises and async/await, array methods (map, filter, reduce), destructuring, event loop. React interviews often start there.
  5. Deploy your best project and polish the README.
  6. Do at least three mock interviews aloud, with a friend, or an AI mock-interview tool such as InterviewAI, and review your answers.
Prompt · Mock React interview
Act as a frontend interviewer hiring for a [fresher / 2-year experience] React developer role. Ask me one question at a time on [React fundamentals / hooks / performance / state management]. After each of my answers, give brief feedback: what was correct, what was missing or wrong, and one follow-up question. Start with an easy question and raise the difficulty if I answer well. After 8 questions, summarise my strengths and the three topics I should revise.

What to expect: Answer aloud or type full sentences, as in a real interview. Verify any technical correction from the AI against the official React documentation.

Try it: Teach it back

Choose any five questions from the tables. For each, record yourself (phone voice recorder) answering in under 60 seconds with one tiny code example or analogy. Listen back and note filler words, missing points and anything you could not explain. Re-record the weakest two.

Key takeaways

  1. Know the fundamentals deeply: JSX, props vs state, keys, controlled inputs, the virtual DOM and why re-rendering happens.
  2. Hooks: rules, effect dependency arrays and cleanup, useRef, useMemo/useCallback, custom hooks.
  3. Be able to explain the classic bugs: stale state (use functional updates), mutating state, effect loops, StrictMode double effects.
  4. Answer architecture questions by classifying state and choosing the simplest tool; always measure before optimising.
  5. In live coding, clarify requirements, build a working simple version first, and handle loading, empty and error states.
  6. Prepare a one-minute project story with a real problem you solved, and never bluff.

Check yourself

Finishing the quiz marks the lesson as done.

1. A button handler calls setCount(count + 1) three times. After one click the count is 1. Why?

2. What is the most accurate description of the virtual DOM?

3. An effect with no dependency array calls setState each time it runs. What happens?

4. In a live coding round you are asked to build a todo list. What is the best first move?

5. Which is a good reason NOT to put something in useEffect?

Saved on this device. Create a free account to keep it on every device.

Practise this with Sam

A real mock interview, out loud, with an honest scorecard. Free to start.

Start free