你好,React setState

React用了有一段时间了,抽空写分析一下setState。

卧槽,刚要写词穷了。

 

关于react组件挂载、刷新、卸载都执行了那些,流程的概念如果不清楚请看这里

好啦进入正题,在react入门中我们经常接触到的就是createClass \ render\getInitialState等一下相关方法和生命周期的方法。为了让数据灵活性的变更,组件内部变化让组件变成一个活组件,我们用到了setState,用起来挺爽,改什么setState一下,ok啦,要是追本溯源setState干了啥,那些地方set了会被合并set,那些是reRender呢?

 

嗯本宝宝要开始吹牛逼了。

 

先上个图来源

 

/**
 * Mark a component as needing a rerender, adding an optional callback to a
 * list of functions which will be executed once the rerender occurs.
 */
function enqueueUpdate(component) {
  ensureInjected();

  // Various parts of our code (such as ReactCompositeComponent's
  // _renderValidatedComponent) assume that calls to render aren't nested;
  // verify that that's the case. (This is called by each top-level update
  // function, like setProps, setState, forceUpdate, etc.; creation and
  // destruction of top-level components is guarded in ReactMount.)

  if (!batchingStrategy.isBatchingUpdates) {
    batchingStrategy.batchedUpdates(enqueueUpdate, component);
    return;
  }

  dirtyComponents.push(component);
}

  简单说来,React 内部有一个ReactDefaultBatchingStrategy文件,这个家伙主要管的就是更新State的,它在React实例化的时候就被注入到ReactUpdates的类,它很傲娇,每次更新state的时候都会将isBatchingUpdates锁定。这个时候如果有setState到来的时候全部放入dirtyComponents队列里,等待锁定状态解除了将所有存储的state状态设定拿出来进行合并,然后render,反之如果isBatchingUpdates没有被锁定则直接render。

 

说了一段大白话,敢举个例子说一下嘛?

 例子来了,网上都会拿这个例子来说

 

 

看一下这个setState在那里设置,componentDidMount,原来是组件挂载完成啊。

直观理解1、2、3、4哈哈那就错了。上边有提到傲娇的isBatchingUpdates了吧。先看看componentDidMount的时候它的状态。

为毛才说,好吧我们开始一段state(以下简称BU)的诡(jie)异(ke)之旅,当然setState就是state的代(lao)言(ma)人(zi),来看看那里state我们的傲娇妹纸会接受呢(奸笑脸能不能set的幕后推手isBatchingUpdates)?

 

getDefaultProps 对于一个组件只初始化一次的大叔来说,state还没出生呢,不接。

getInitialState 这里也是set不了,妹纸内心OS:不要脸,人家刚刚初始化,你就你就要set一下,滚。(but state的初始化值就来自于这里)

componentWillMount 啦啦啦 我是除了init那家伙(给定初始值)以外第一个可以调用setState的人(yin),这是setState时isBatchingUpdates还是false耶,所以state会合并一次render到DOM(看这里,只render一次哦),然后isBatchingUpdates被锁定了。

 

 

 

 

 

render 上边的一堆都是啥,最后我才是state的接盘侠,这里如果有条件的setState,由于isBatchingUpdates已经处于锁定状态,所以set的值会放入等待队列,然后ComponentDidMount调用结束后reRender。

 

 

 

 

componentDidMount  我来了,卧槽前面有个妹纸(state),but她不喜欢我,willMount追了她,我反复的追她,她不理我,

因为isBatchingUpdates还在锁定中,

好消息是我成了state妹纸的备胎(放入等待队列),坏消息是我走了以后妹纸的资源才会被释(fen)放(shou),一个不好不坏的消息,等我从备胎变成了千斤顶,最终还是交给了render。

 

 

 

好了说说说上边的例子执行流程和结果。

第一次setState 由于状态锁定中,所以val被放入待更新队列,第二次也是一样

然后componentDidMount执行完毕,锁定状态解除,妹纸单身啦。然后他们两个setState作为一次合并在一起,然后更新state,这个时候state变成了1.(reRender)

第三次 setState 这时候锁定状态已经解除,来者不拒,所以第三次reRender

第四次依旧是reRender

 

 

 

 

posted on 2016-07-01 14:57  牛-_-蜗  阅读(3587)  评论(4编辑  收藏  举报

导航