拆解setState[一][一源看世界][之React]

有惊无险地看完了setState源码的精彩内容,正打算整理一下激动的情绪,梳理一下逻辑,记下读后感,然后就在React功夫网发现了同样介绍setState的文章,感觉作者的思路很清晰,所以就打算在参考它的基础上把这篇文章给撸完。
go go go ...

首先得先找到入口,在ReactClass.createClass声明构造函数的代码中Constructor.prototype = new ReactClassComponent();,可以看出构造函数的原型继承自ReactClassComponent,而ReactClassComponent的源码如下:

var ReactClassComponent = function() {};
Object.assign(
  ReactClassComponent.prototype,
  ReactComponent.prototype,
  ReactClassMixin
);

ReactClassComponent的原型又合并了ReactComponent的原型,所以构造函数Constructor的原型也就有了ReactComponent.prototypesetState的方法。
SO,我们看一下ReactComponent.prototype.setState的方法实现吧。

首先看下这个方法的注释

Sets a subset of the state. Always use this to mutate
state. You should treat this.state as immutable.

There is no guarantee that this.state will be immediately updated, so
accessing this.state after calling this method may return the old value.

There is no guarantee that calls to setState will run synchronously,
as they may eventually be batched together. You can provide an optional
callback that will be executed when the call to setState is actually
completed.

When a function is provided to setState, it will be called at some point in the future (not synchronously). It will be called with the up to date component arguments (state, props, context). These values can be different from this.because your function may be called after receiveProps but before shouldComponentUpdate, and this new state, props, and context will not yet be assigned to this.

提取一下上面的大概中心思想:

  1. 通过setState去更新this.state不要直接操作this.state,请把它当成不可变的。
  2. 调用setState更新this.state不是马上生效的,它是异步滴,所以不要天真以为执行完setStatethis.state就是最新的值了。
  3. 多个顺序执行的setState不是同步地一个一个执行滴,会一个一个加入队列,然后最后一起执行,即批处理

那,有了个大概认识,就开始深入探险吧,Let's go...

ReactComponent.prototype.setState = function(partialState, callback) {
  ...
  this.updater.enqueueSetState(this, partialState);
  if (callback) {
    this.updater.enqueueCallback(this, callback, 'setState');
  }
};
  • setState被加入updater的队列来执行它的工作。
  • callback也被加入updater的队列,如果存在的话。

别急,接下来你会明白为什么的。

updater是什么呢?这个名称意味着它会与更新组件有关。先来看看它在哪里定义吧。在ReactClass.createClassReactComponent的构造函数中,可以看到

this.updater = updater || ReactNoopUpdateQueue;

React的源码中大量应用依赖注入原理,这使得React.js可以优雅地实现在不同平台下(服务器端,浏览器端,手机端等)的渲染。ReactComponent脚本存在于isomorphic目录 - 意味着它支持异构,即它可用于React Native,在浏览器端或服务器端运行的ReactDOM

那,真实的updater在哪里被注入的呢?那就得知道ReactComponent Class在哪里被New,经过千山万水,终于在ReactCompositeComponent_constructComponentWithoutOwner方法中找到

  _constructComponentWithoutOwner: function(publicProps, publicContext) {
    var Component = this._currentElement.type;
    var instanceOrElement;
    if (shouldConstruct(Component)) {
      ...
      instanceOrElement = new Component(publicProps, publicContext, ReactUpdateQueue);
      ...
    } else {
      ...
    }
    return instanceOrElement;
  },

可以看出updaterReactUpdateQueue,这就真的找到了吗?其实不然,我们顺着往上找,经过_constructComponent,最终定位到mountComponent,从这句代码inst.updater = ReactUpdateQueue;可以看出最终的updater,还是ReactUpdateQueue,哈哈,虽然没变,但最终决定updater的值确实就是这里。

OK,知道了这个updater的真面目,那~,我们先休息一下吧,在下章节我们再来深入了解enqueueSetStateenqueueCallback是怎么工作的吧。


最后,期待吐槽,期待指教!!!

--EOF--

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,369评论 0 23
  • 每颗珍珠原本都是一粒沙子,但并不是每一粒沙子都能成为一颗珍珠。想要卓尔不群,就要有鹤立鸡群的资本。忍受不了打击和挫...
    张伟kk阅读 188评论 0 1
  • 正是农历的七月,七夕刚过去不久,还听得见躲在树叶里的蝉鸣。又是一年暑假,宅在家里已经四五天,都说开卷有益,这闲散的...
    踏雪听香阅读 501评论 7 14