引入
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