React setState 批量更新机制
理解 React 中多次调用 setState 时的批量更新行为
问题
下面代码中,点击 “+3” 按钮后,age 的值是什么?
import { useState } from 'react';
export default function Counter() {
const [age, setAge] = useState(42);
function increment() {
setAge(age + 1);
}
return (
<>
<h1>Your age: {age}</h1>
<button onClick={() => {
increment();
increment();
increment();
}}>+3</button>
</>
);
}
解答
点击 “+3” 按钮后,age 的值是 43,而不是 45。
这是因为 setAge(age + 1) 使用的是当前渲染时的 age 值(42)。三次调用都是基于同一个值计算:
- 第一次:
setAge(42 + 1)→ 43 - 第二次:
setAge(42 + 1)→ 43 - 第三次:
setAge(42 + 1)→ 43
React 会将这些更新合并,最终只触发一次重新渲染,结果为 43。
正确的做法是使用函数式更新:
function increment() {
setAge(a => a + 1); // 基于上一次的状态值更新
}
这样每次调用都会基于最新的状态值计算:
- 第一次:
a => 42 + 1→ 43 - 第二次:
a => 43 + 1→ 44 - 第三次:
a => 44 + 1→ 45
关键点
setState不会立即更新状态,而是在事件处理完成后批量处理- 多次调用
setState(value)使用的是同一个快照值,会被合并 - 使用函数式更新
setState(prev => newValue)可以基于最新状态计算 - 函数式更新确保每次更新都基于上一次的结果,适合连续更新场景
目录