React 之 setState

react

前言:

    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

回到顶部