How to Debug React State Updates With AI: A Worked Example
Reproduce a React state-update bug, write a focused debugging prompt, inspect the fix, and verify the expected behavior with a small runnable exercise.

In this guide
When a React button should add two seats but adds only one, asking an AI assistant to “fix the counter” is too vague. Give it a reproducible input, the expected result, and a narrow editing boundary. Then check the patch yourself.
This tutorial uses a deliberately small teaching example. It is not a comparison of AI products. You need an existing React project with a client-rendered component to try the interaction.
1. Reproduce the unexpected result
Start with this component. In a Next.js App Router project, keep the client directive at the top. In another React setup it is not required.
'use client';
import { useState } from 'react';
export default function SeatPicker() {
const [seats, setSeats] = useState(0);
function reservePair() {
setSeats(seats + 1);
setSeats(seats + 1);
}
return (
<section>
<p>Reserved seats: {seats}</p>
<button onClick={reservePair}>Reserve two seats</button>
</section>
);
}
Starting from zero, the expected result after one click is two. The example instead requests the value one twice. Record that observation before changing the code; it is the acceptance criterion for the fix.
2. Ask for a diagnosis before a rewrite
Paste only the component and this prompt into your chosen coding assistant:
This button should add two seats per click. From zero, one click produces one instead of two. Explain how this event handler uses state, then propose the smallest fix inside reservePair. Preserve the component interface and markup. Give checks for one click, two clicks, and a nonzero starting value. Do not add a package or an effect.
This prompt constrains the change without assuming the assistant has identified the cause. If it recommends replacing the entire component, ask which part of the reported behavior requires that rewrite. If it suggests waiting for a timeout, ask how that establishes the correct state transition.
3. Inspect the proposed change
React documents state as a snapshot for a render. Calling a setter does not change the state variable already captured by the current handler. For queued changes that depend on the previous value, updater functions receive the pending state. State as a snapshot and queued state updates explain this behavior.
For this example, a compact fix expresses the intended change directly:
function reservePair() {
setSeats(previousSeats => previousSeats + 2);
}
If your real handler needs two separate increments, two updater calls can express those individual changes. Here one updater is easier to read because the button represents a single operation: reserve a pair.
