State with useState
useState gives a component memory that persists between renders.
Syntax
const [count, setCount] = useState(0);State is data a component remembers between renders. You add state with the useState hook, which returns the current value and a function to update it.
How a state update works
Calling the setter tells React the value changed. React then re-renders the component with the new value, and the screen updates. State is not changed in place — you always call the setter.
Example
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount((c) => c + 1)}>
Clicked {count} times
</button>
);
}When to use it
- A shopping cart counter uses useState to track how many items have been added so the badge in the nav bar updates instantly on each click.
- A multi-step wizard stores the current step index in useState and advances it when the user clicks Next, keeping the progress bar in sync.
- A toggle component persists its open/closed state across renders with useState so collapsible sidebars stay open when the user navigates within the same session.
More examples
Counter with useState
Demonstrates the canonical useState pattern: reading the current value and calling the setter to trigger a re-render.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
);
}Functional updater for derived state
Uses the functional updater form (prev => prev + 1) to safely compute the next value from the previous state.
import { useState } from 'react';
function LikeButton() {
const [likes, setLikes] = useState(0);
const handleLike = () => setLikes(prev => prev + 1);
return <button onClick={handleLike}>Like ({likes})</button>;
}Object state update pattern
Shows how to hold multiple fields in a single state object and update individual fields without losing the others.
import { useState } from 'react';
function ProfileForm() {
const [form, setForm] = useState({ name: '', email: '' });
const update = field => e =>
setForm(prev => ({ ...prev, [field]: e.target.value }));
return (
<form>
<input value={form.name} onChange={update('name')} placeholder="Name" />
<input value={form.email} onChange={update('email')} placeholder="Email" />
</form>
);
}
Discussion