React: From Components to Production · State, Events and Effects
useState and Event Handling
Store component state, update it correctly and handle events.
useState returns the current value and a setter. Setting state schedules a re-render; the new value is visible on the next render, not immediately. Use the updater form (setCount(c => c + 1)) when the next state depends on the previous one, and never mutate state objects — create new ones. Event handlers receive synthetic events with the same interface as native ones.
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
const [profile, setProfile] = useState({ name: "", tags: [] as string[] });
function addThree() {
setCount((c) => c + 1); // updater form: queued updates use the latest value
setCount((c) => c + 1);
setCount((c) => c + 1);
}
function addTag(tag: string) {
setProfile((p) => ({ ...p, tags: [...p.tags, tag] })); // new objects, no mutation
}
return (
<div>
<button onClick={addThree}>+3 ({count})</button>
<input value={profile.name} onChange={(e) => setProfile((p) => ({ ...p, name: e.target.value }))} />
<button onClick={() => addTag("react")}>Add tag</button>
</div>
);
}
Common pitfalls
- Reading state right after setting it and expecting the new value.
- Mutating arrays/objects (
state.push(x)) — React won't re-render. - Calling the handler during render:
onClick={handle()}instead ofonClick={handle}.
Key points
- State updates are asynchronous snapshots
- Use updater functions for derived updates
- Never mutate state
Further reading: react.dev: State
Practice questions
Why does calling setCount(count + 1) three times only add 1?
Answer
All three calls read the same count from the current render snapshot. Use setCount(c => c + 1) so each update builds on the previous queued value.
Why doesn't items.push(newItem); setItems(items) re-render?
Answer
The array reference didn't change, so React bails out. Create a new array: setItems([...items, newItem]).
Open in the app to mark lessons complete, take notes and track your progress.