React

react的setState使用详解

2019-08-01  本文已影响0人  Mr无愧于心

react修改状态是不能直接修改的,需要使用setState来进行状态的修改,但是setState的使用会存在一些问题。觉得有必要在此做一下总结。。。。

setState()不是立刻更新组件。其可能是批处理或推迟更新。这使得在调用setState()后立刻读取this.state的一个潜在陷阱。

就像这样:

incrementCount() {
  this.setState({count: this.state.count + 1});
}
handleSomething() {
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
}
调用了3次incrementCount方法, 期望this.state.count的值是3, 但最后却是1

本质上setState修改state的值是通过浅合并把新的值合并到state的对象上,如果多次修改,react会进行批次处理

类似于:

Object.assign(
  previousState,
  {count: state.count + 1},
  {count: state.count + 1},
  {count: state.count + 1},
)
之后的调用在同一周期中将会重写之前调用的值,因此数量仅会被加一。若之后的状态依赖于之前的状态,

解决这个问题的方式:

componentDidUpdate或一个setState回调(setState(updater, callback))

  1. 当中的每个方法都会保证在更新被应用之后触发
  2. updater函数接收到的prevState 和 props保证都是最新的
incrementCount() {
  this.setState((state) => {
    return {count: state.count + 1}
  });
}
handleSomething() {
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
}

setState什么时候会异步更新

setState的执行流程:

this.setState(newState)
==>
newState存入pending队列
==>
判断是否处于batch update
==>
如果是的话就保存组件月dirtyComponents中,
如果不是的话就遍历所有的dirtyComponents,调用updateComponent,更新pending state or props

在 React 的 setState 函数实现中,会根据一个变量 isBatchingUpdates 判断是直接更新 this.state 还是放到队列中回头再说,
而 isBatchingUpdates 默认是 false,也就表示 setState 会同步更新 this.state,
但是,有一个函数 batchedUpdates,这个函数会把 isBatchingUpdates 修改为 true,
而当 React 在调用事件处理函数之前就会调用这个 batchedUpdates,造成的后果,就是由 React 控制的事件处理过程 setState 不会同步更新 this.state。


setState什么时候会异步更新, 什么时候会同步更新

React是根据isBatchingUpdates来合并更新的, 那么当调用setState的方法或者函数不是由React控制的话, setState自然就是同步更新了。

  1. 如componentDidMount等生命周期以及React的事件即为异步更新,这里不显示具体代码。
  2. 如自定义的浏览器事件,setTimeout,setInterval等脱离React控制的方法, 即为同步更新
上一篇下一篇

猜你喜欢

热点阅读