Skip to content

React Tutorial Modern React and Production

Debugging React Applications: DevTools, Console and Common Bugs

Lesson 130 of 156 4 min read By Deepak Paswan Updated Oct 10, 2026

Runnable lesson · press Try it on the examples to edit and run them here.

Debugging is a skill with a method. React errors look scary, but they are usually precise. This lesson gives you a routine and the tools.

Step 1: read the error, from the top

React and the browser tell you a lot:

  • The message: “Cannot read properties of undefined (reading ‘name’)” means you used x.name while x was undefined.
  • The file and line: click it in the console to open the code.
  • The component stack React adds (“The above error occurred in the <ProductCard> component”). It tells you which component to look at.
  • Warnings: missing keys, invalid DOM attributes, controlled/uncontrolled inputs, state updates in render. They are bugs waiting to happen. Fix them all.

Fix the first error first. Later ones are often just consequences.

Step 2: look at the data

Most React bugs are “the data is not what I think”. Show it:

App.jsx
JSX
function App() {
  const [id, setId] = React.useState(1);
  const user = { id, name: "Ada", roles: ["admin", "editor"] };

  // 1. console.log shows the values in the console panel
  console.log("render with", user);

  // 2. console.table is nicer for arrays of objects
  console.table([{ id, name: "Ada" }, { id: id + 1, name: "Grace" }]);

  return (
    <div>
      <h3>Debug view</h3>
      {/* 3. Show an object on the page while developing */}
      <pre>{JSON.stringify(user, null, 2)}</pre>
      <p>id={id}</p>
      <button onClick={() => setId(id + 1)}>Next id</button>
    </div>
  );
}

Tips:

  • Put the console.log at the top of the component to see every render and the props and state it received.
  • Label your logs: console.log("user:", user), not console.log(user).
  • Remove debug logs before you commit.
  • JSON.stringify on the page is a quick way to see state without the console.

Step 3: React Developer Tools

The browser extension adds two tabs to the developer tools:

  • Components: the tree of your components. Click one to see its props, state and hooks, and even edit them live to test behaviour. Use the search box to find a component and the “inspect” button to pick one from the page.
  • Profiler: record an interaction to see which components rendered and how long each took. Turn on “Highlight updates when components render” in the settings to see re-renders as flashing outlines.

Ask: are the props and state what I expect? If yes, the bug is in the rendering logic. If no, find where they were set wrong, going up the tree.

Step 4: breakpoints

A breakpoint pauses the program so you can inspect every variable. Open the Sources panel in the browser developer tools, find your file (source maps show the original code), and click a line number. Or write debugger; in the code: when developer tools are open, the page stops there. Then step through line by line and watch variables (Debugger and Breakpoints). It beats adding ten console.log calls.

Step 5: the Network panel

For data problems, open the Network tab: did the request go out? To which URL? What status came back? What did the response body contain? Many “my component is empty” bugs are a 404, a 500 or a different JSON shape (Network Panel).

Common symptoms and likely causes

SymptomLikely cause
Screen does not update after a clickMutated state instead of setting a new value (Avoiding State Mutation)
Handler sees an old valueStale closure or snapshot (State as a Snapshot)
Infinite loop, “Too many re-renders”Setting state during render; effect that sets its own dependency
“Cannot read properties of undefined”Data not loaded yet, or the shape differs; use optional chaining and loading states
Input loses focus on every keystrokeA component defined inside another component (Common Rendering Mistakes)
Effect runs twiceStrict Mode, on purpose; fix cleanup (Strict Mode)
List items swap stateMissing or index keys (Keys)
Blank pageAn uncaught render error (read the console), or a wrong path in production
Works in dev, breaks in productionWrong base, missing env variable, case-sensitive file names (Common Production Errors)

A bug to find

This counter is supposed to add one per click, but nothing happens. Run it, press the button and check the console panel and the screen. Then fix it.

App.jsx
JSX
function App() {
  const [items, setItems] = React.useState([]);

  function add() {
    items.push("x");     // what is wrong here?
    setItems(items);
  }

  return (
    <div>
      <p>Count: {items.length}</p>
      <button onClick={add}>Add</button>
    </div>
  );
}

The array is mutated and then given back to React as the same reference, so React sees no change. The fix is setItems([...items, "x"]):

App.jsx
JSX
function App() {
  const [items, setItems] = React.useState([]);

  function add() {
    setItems([...items, "x"]);
  }

  return (
    <div>
      <p>Count: {items.length}</p>
      <button onClick={add}>Add</button>
    </div>
  );
}

A debugging routine

  1. Reproduce the bug and find the smallest steps that trigger it.
  2. Read the first error and the component stack.
  3. Check the data (props, state, network response).
  4. Form a guess, and test it with a log or a breakpoint.
  5. Fix one thing at a time.
  6. Add a test so it cannot come back (Basic Testing Concepts).

When you are stuck, make a minimal example in the playground: removing everything that is not part of the problem often reveals the cause, and gives you something small to ask about.

Key points

  • Read the first error and the component stack; fix warnings too.
  • Inspect data with logs, React DevTools, breakpoints and the Network panel.
  • Match the symptom to the usual cause, and reduce the problem to a minimal example.