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 DOMState 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
- React Documentation — State: A Component's Memory
- React Documentation — useState Reference
- React Documentation — Queueing a Series of State Updates
- React Documentation — Updating Objects in State
The Codex links only to official documentation. No third-party tutorials.