• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

React:useState的异步更新

互联网 diligentman 1周前 (11-21) 6次浏览

引入

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…

  • 我们知道:

    1. useState每次执行会返回一个新的state(简单类型的等值拷贝)
    2. setState会触发UI更新(重新render,执行函数组件)
    3. 由于UI更新是异步任务,所以setState也是一个异步过程

当我们两次setN(n+1)时候,实际上形成了两个闭包,都保存了对此时n的状态(n=0)的引用。
在setN后:

  1. 先分别生成了两个新的n,数值上都等于n+1(即1),但彼此无关。
  2. 分别进行了render,而只有最新一次render有效,此次render引用了最后一次setN函数里生成的n。

解决方法

// 利用函数,接收旧值,进行更新
setState( x => x+1 )
  • 接收的函数 x=>x+1 并未保持对n的引用,而是表达了一种 加1 操作
  • 推荐使用函数代码进行 setState

喜欢 (0)