引入
function App() {
const [n, setN] = useState(0)
const onClick = ()=>{
setN(n+1)
setN(n+1) // 此时发现,n只能+1,而不会+2
// setN(i=>i+1)
// setN(i=>i+1)
}
return (
<div className="App">
<h1>n: {n}</h1>
<button onClick={onClick}>+2</button>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
react代码如上图:
- 直觉上当我们点击button,应该会执行两次setN,n变为2。
- 实际上:n变为了1
为什么n是1,而不是2?
首先要搞清楚useState的原理,可以参考我的博客,讲解了useState的简易实现:https://segmentfault.com/a/11...
我们知道:
- useState每次执行会返回一个新的state(简单类型的等值拷贝)
- setState会触发UI更新(重新render,执行函数组件)
- 由于UI更新是异步任务,所以setState也是一个异步过程
当我们两次setN(n+1)
时候,实际上形成了两个闭包,都保存了对此时n的状态(n=0)的引用。
在setN后:
- 先分别生成了两个新的n,数值上都等于n+1(即1),但彼此无关。
- 分别进行了render,而只有最新一次render有效,此次render引用了最后一次setN函数里生成的n。
解决方法
// 利用函数,接收旧值,进行更新
setState( x => x+1 )
- 接收的函数
x=>x+1
并未保持对n的引用,而是表达了一种 加1 操作 - 推荐使用函数代码进行
setState
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。