React中useState的两种setCount写法为何执行效果不同?
React useState中两种setState写法的差异解析
先看你提供的示例代码:
const Counter = () => { const [count, setCount] = React.useState(0); const increase1 = () => { setCount(count + 1); setCount(count + 1); setCount(count + 1); }; const increase2 = () => { setCount((count) => count + 1); setCount((count) => count + 1); setCount((count) => count + 1); }; console.log(count); return <button onClick={increase1}>Increase</button>; };
两种写法的核心差异在于setState获取状态值的方式,结合React的批量更新机制,导致了最终结果不同:
1. increase1:直接传值的更新方式
setCount(count + 1)这种写法,是直接取用当前函数闭包中的count值进行计算。
React会对同一事件循环内的多个状态更新做批量处理,当你连续调用三次setCount(count + 1)时:
- 三次调用里的
count都是当前闭包中的固定值(比如初始为0,三次计算都是0+1) - 批量更新最终只会生效最后一次的计算结果,所以点击一次后
count从0变成1 - 多次点击时,每次点击都基于当时的
count值加1,因此呈现1→2→3的递增节奏
2. increase2:函数式更新方式
setCount((prevCount) => prevCount + 1)这种函数式写法,会让React把上一次状态更新后的最新值作为参数传入回调函数。
同样是三次连续调用:
- 第一次调用时,
prevCount为初始值0,计算后状态变为1 - 第二次调用时,
prevCount取上一次更新后的1,计算后状态变为2 - 第三次调用时,
prevCount取2,计算后状态变为3 - 批量更新完成后,
count直接从0跳变为3 - 多次点击时,每次点击都会基于最新的
count执行三次累加,因此呈现3→6→9的递增节奏
总结:直接传值依赖的是当前闭包的状态快照,函数式更新依赖的是实时的最新状态。当需要在一次事件中多次更新同一状态时,函数式更新能保证每次更新都基于最新值,避免闭包导致的状态过期问题。
内容的提问来源于stack exchange,提问作者GoonGamja
相关产品推荐
相关产品推荐

