React中useState两种状态更新实现写法的区别是什么
React useState 两种状态更新写法的差异
我们先回顾你给出的两种写法:
const [count, setCount] = useState(0); // 第一种:直接传新值 setCount(count + 1); // 第二种:传入更新函数 setCount(prevCount => prevCount + 1);
二者的核心差异在于获取状态值的来源不同,适用场景也有区别:
- 直接传值的写法,依赖的是当前渲染闭包中拿到的
count值,这个值在本次渲染周期内是固定不变的。如果在同一个渲染周期内多次调用这种写法的更新,只会生效最后一次:比如你连续写三次setCount(count + 1),最终count只会加1,因为三次调用拿到的都是同一个初始count值,相当于反复把状态设置为同一个值。 - 函数式更新的写法,入参
prevCount永远指向状态的最新值,不受当前闭包的限制。就算在同一个渲染周期内连续调用三次,每次都会基于上一次更新后的结果计算新值,最终count会正常累加3。
适用场景区分
- 直接传值写法适合更新和旧状态无关的新值,比如直接把
count重置为0,写法更简洁直观。 - 函数式更新写法适合需要基于旧状态计算新值的场景,尤其是异步回调(setTimeout、接口请求回调)中更新状态的场景,能规避闭包陷阱导致的拿到旧状态值的问题。
给一个常见的反例方便理解:
const [count, setCount] = useState(0); const handleClick = () => { setTimeout(() => { // 这里的count是handleClick触发时闭包里的旧值,如果在setTimeout执行前用户多次点击,拿到的count不是最新的 setCount(count + 1); // 换成函数式更新就能拿到最新的count值,不会出现更新错误 // setCount(prev => prev + 1) }, 1000) }
内容的提问来源于stack exchange,提问作者Yamila
相关产品推荐
相关产品推荐

