The Codex / Technologies / React / State & useState

State & useState

Giving components memory - how useState works, the rules of hooks, and updating state correctly (including the stale closure trap).

What it is, in plain English: State is data that a component remembers between renders and can change over time. useState is the React Hook that adds state to a function component. Calling the setter function (returned by useState) tells React the data changed, which triggers a re-render with the new value. Unlike props (which come from a parent), state is owned and managed by the component itself.

Giving a component memory

Props let data flow INTO a component, but a component can't change its own props. When a component needs to remember something and change it over time — a counter, form input, toggle — it needs state.

useState — the basic pattern

function Counter() {
  // useState(0) — 0 is the initial value
  // Returns an array: [currentValue, functionToUpdateIt]
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

// Every time setCount is called:
// 1. React updates the stored value
// 2. The component function runs AGAIN (re-render)
// 3. The new 'count' value appears in the new JSX
// 4. React updates only the changed part of the real DOM

State can be any type

const [name, setName]       = React.useState("");        // string
const [isOpen, setIsOpen]   = React.useState(false);      // boolean
const [items, setItems]     = React.useState([]);         // array
const [user, setUser]       = React.useState(null);       // object or null

function Toggle() {
  const [isOn, setIsOn] = React.useState(false);
  return (
    <button onClick={() => setIsOn(!isOn)}>
      {isOn ? "ON" : "OFF"}
    </button>
  );
}

The Rules of Hooks

Hooks must be called the same way, every render. Never call useState (or any hook) inside a loop, condition, or nested function. This is non-negotiable — React relies on hooks being called in the exact same order every time.
// ✗ WRONG — conditional hook call:
function Bad({ condition }) {
  if (condition) {
    const [x, setX] = React.useState(0);  // breaks the rules!
  }
}

// ✓ RIGHT — always call the hook, use the condition inside:
function Good({ condition }) {
  const [x, setX] = React.useState(0);
  if (condition) {
    // use x here
  }
}
Try It Yourself (JSX)

Official Sources

The Codex links only to official documentation. No third-party tutorials.