How does useState work?
Solution and explanation
What it is
useState gives a function component a piece of state that survives re-renders.
const [count, setCount] = useState(0);
countis the current value for this render.setCount(newValue)schedules a re-render with the new value.0is the initial value, used only on the first render.
How React stores it
React keeps a list of hooks for each component instance and matches them **by call order**. That is why hooks must be called at the top level, never inside conditions or loops:
if (loggedIn) { const [x] = useState(); } // wrong: order changes between renders
Updates are asynchronous and batched
function handleClick() {
setCount(count + 1);
setCount(count + 1); // still count + 1: both read the same old value
}
function handleClickFixed() {
setCount(c => c + 1);
setCount(c => c + 1); // + 2: functional update uses the latest value
}
Use the **functional form** whenever the new state depends on the old state.
Objects and arrays
State must be replaced, not mutated:
const [form, setForm] = useState({ name: '', email: '' });
setForm(prev => ({ ...prev, email: 'a@b.com' }));
const [skills, setSkills] = useState([]);
setSkills(prev => [...prev, 'React']); // add
setSkills(prev => prev.filter(s => s !== 'PHP')); // remove
React compares with Object.is; mutating the same object keeps the same reference, so React skips the re-render.
Lazy initial state
const [draft, setDraft] = useState(() => JSON.parse(localStorage.getItem('draft') ?? '{}'));
The function runs only on the first render, so expensive work is not repeated.
Summary
useState returns the current value and a setter; updates are batched, use functional updates for derived values, and never mutate objects or arrays.
