useState
The useState hook adds local state to a function component. It returns the current value and a setter; calling the setter triggers a re-render with the new value.
Counter, form field, lazy init
EXAMPLE
import { useState } from 'react';
// 1) Basic counter
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={() => setCount(c => c + 1)}>+1 (functional)</button>
</div>
);
}
// 2) Functional updater — when next state depends on previous
function RapidClicks() {
const [n, setN] = useState(0);
return (
<button onClick={() => {
setN(c => c + 1); // safely batched
setN(c => c + 1); // +2 total, not +1
}}>+2</button>
);
}
// 3) Form field — single source of truth
function NameForm() {
const [name, setName] = useState('');
return (
<input value={name} onChange={(e) => setName(e.target.value)} />
);
}
// 4) Object state — spread to preserve other fields
function Profile() {
const [user, setUser] = useState({ name: '', email: '', age: 0 });
return (
<input
value={user.email}
onChange={(e) => setUser({ ...user, email: e.target.value })}
/>
);
}
// 5) Lazy initial state — expensive compute runs ONCE
function Tree() {
const [tree, setTree] = useState(() => buildHugeTree()); // function, not value
// buildHugeTree() runs on mount, not on every render
}
// 6) Multiple states — usually cleaner than one big object
function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [busy, setBusy] = useState(false);
}
// 7) State is replaced, not merged — different from class setState
const [pos, setPos] = useState({ x: 0, y: 0 });
setPos({ x: 10 }); // y is now undefined!
setPos((p) => ({ ...p, x: 10 })); // correct
Why it matters
Use a functional updater (setN(c => c + 1)) any time the new value depends on the previous one. It survives React batching and any race against stale closures.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
const [count, setCount] = useState(0); const increment = () => setCount(c => c + 1);Try it Yourself »
Discussion
Loading…