The stateuseState & re-renders

I don’t need state for a simple counter.

You don’t — for the counting. A component is a function: render means React calls it and paints what it returns. A let inside that function is born in the call and dies with it, so adding one to it works — and changes nothing on screen, because changing a value and repainting the screen are two different jobs. useState is how a counter gets both: the setter stores the value where React keeps it between calls, and it schedules the call — the render — that paints it.

Press +1 and the number moves, the way counters always have. Now flip narrate and press again: the card turns over and replays the render against its own source — React runs StateCard() again, top to bottom, useState hands back the value it kept, and the line that paints the count paints the new one. Then the card turns back, and the number has moved. Everything in the replay happened before the card finished turning. It is slowed, not simulated, and the values in it were read live.

live
useStatestate-card.tsx

0

  • setCount stores the value where React keeps it
  • then React calls the component again

a state variable is a value React keeps between calls — and setting it is permission to call the component again.

state-card.tsx
// state-card.tsx
"use client";

import { useState } from "react";

export function StateCard() {
  const [count, setCount] = useState(0);
  // setCount does both jobs: it stores the value where React keeps it
  // between calls, and it schedules the render that repaints the screen.
  return (
    <Card pill="useState">
      <button onClick={() => setCount(count + 1)}>+1</button>
      <p>{count}</p>
    </Card>
  );
}