React 之 setState
前言:
state是React中非常重要的概念。React通过管理状态来实现对组件的管理,React通过this.state来访问state,又通过this.setState()来更新state,当this.setState()方法被调用时,React会重新调用render函数来重新渲染UI。
一、setState异步更新
setState通过一个队列机制实现state更新。当执行setState时,会将需要更新的state合并后放入状态队列,而不会立刻更新this.state,队列机制可以高效批量更新state。如果不通过setState而直接修改this.state的值,那么该state将不会被放入状态队列中,当下次调用setState并对队列进行合并时,将会忽略之前直接被修改(例:this.state.value=1)的state,而造成无法预知的错误。
相关代码如下:
//将新的state合并到状态更新队列中var nextState = this._processPendingState(nextProps,nextContext);
//根据更新队列和 shouldComponentUpdate 的状态来判断是否需要更新组件
var shouldUpdate =
this._pendingForceUpdate ||
!inst.shouldComponentUpdate ||
inst.shouldComponentUpdate(nextProps,nextState,nextContext);
setState()方法是一个异步函数,可以传入回调函数。this.setState({...state},callback);
二、setState循环调用风险
当调用setStae()方式时,实际上会执行enqueueSetState方法,并对partialState以及_pendingStateQueue更新队列进行合并操作,最终通过enqueueUpdate执行state更新。
而performUpdateIfNecessary方法会获取_pendingElement、_pendingStateQueue、_pendingForceUpdate,并调用revceviceComponent和updtaComponent方法进行组件更新。
如果在 shouldComponentUpdate或compponentWillUpdate方法中调用setState,此时this._pendingStateQueue!=null,则performUpdateIfNecessary方法就会调用updataComponent方法进行组件更新,但updateComponent方法又会调用shouldComponentUpdate和componentWillUpdate方法,因此造成循环调用,使得浏览器内存沾满后崩溃。
三、setState调用栈
enqueueUpdate
的作用是判断 batchingStrategy.isBatchingUpdates
如果是 true,则对所有队列中的更新执行 batchUpdates
方法,否则只把当前组件(调用了 setState 的组件)放入 dirtyComponents
数组中。
enqueueupdate源码:
function enqueueUpdate(component){ ensureInjected();
// 如果不是批量更新模式
if (!batchingStrategy.isBatchingUpdates){
batchingStrategy.batchingUpdates(enqueueUpdate, component);
return ;
}
// 如果处于批量更新模式 则将该组件保存在 dirtyComponents 中
dirtyComponents.push(component)
}
batchingStrategy
只是定义了一个 Boolean 类型的变量 isBatchingUpdates
和 一个 batchedUpdates
方法:
var ReactDefaultBatchingStrategy = { isBatchingUpdates: false,
batchedUpdates: function(callback, a, b, c, d, e) {
var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
ReactDefaultBatchingStrategy.isBatchingUpdates = true;
if (alreadyBatchingUpdates) {
callback(a, b, c, d, e);
} else {
// transaction.perform 涉及一个事务的概念
transaction.perform(callback, null, a, b, c, d, e);
}
},
}
四、 事务
这里事务的概念如下:
将需要执行的方法使用 wrapper
封装起来,再通过事务提供的 perform
方法执行。
在 perform
之前,先执行所有 wrapper
中的 initialize
方法,执行完 perform
方法之后(执行 method 方法后)再执行所有的 close
方法。
一组 initialize
及 close
方法称为一个 wrapper
,多个 wrapper 可以叠加。
如下图所示:
以上是 React 之 setState 的全部内容, 来源链接: utcz.com/z/381658.html