const [count, setCount] = useState(0):初始值 0,count 是当前值,setCount 是修改函数。状态变了组件自动重新渲染。连续调用 setCount(n+1) 不能拿到最新值——批处理下 n 是闭包里的旧值。要基于前值更新必须用函数式更新:setCount(prev => prev + 1)。
状态更新是「替换」不是「合并」(与 Vue/reactive 的合并式更新不同):setState({ a: 1 }) 会把整个对象替换掉,对象其他字段丢失,要 ...展开旧值。同值更新时 React 会跳过重渲染(Object.is 比较)。复杂状态逻辑(多字段联动、有限状态机)建议 useReducer 集中管理。
function Demo() {
const [count, setCount] = useState(0);
const [user, setUser] = useState({ name: 'Tom', age: 20 });
function add3() {
// ✗ 闭包陷阱:三次都拿到同一个旧 count,只 +1
// setCount(count + 1); setCount(count + 1); setCount(count + 1);
// ✓ 函数式更新:每次基于最新值
setCount(p => p + 1); setCount(p => p + 1); setCount(p => p + 1);
}
function grow() {
// ✓ 替换式更新:必须展开旧字段,否则 name 丢失
setUser(prev => ({ ...prev, age: prev.age + 1 }));
}
return <button onClick={add3}>{count} / {user.name}:{user.age}</button>;
}