资讯专栏INFORMATION COLUMN

【Under-the-hood-ReactJS-Part1】React源码解读

lindroid / 3345人阅读

摘要:回到,事务是中广泛采用的一种模式。先不论包装行为,事务允许应用重置事务流,阻塞一个已经在执行过程中的同步方法等等。我们调用挂载方法,并把它包装进这个事务中,这是为了在挂载动作后,会检查已挂载组件影响到了哪些内容,并更新这些内容。

接上文,

React流程图:
https://bogdan-lyashenko.gith...

事务

到现在这一步,组件实例已经通过某种方式加入到React的生态系统中了,同时,React也会对组件进行一些处理,比如ReactUpdates这个专门的模块。正如大家所知,React是批量处理更新的,也就是说,React会收集所有操作然后一次性操作掉。采用这种方式,一些先置条件和后置条件只需要运行一次,避免了每次更新时都要运行的弊端。

那么React是如何处理这些先置和后置条件的呢?答案就是事务(transaction)。 对于一些人来说这个可能是一个新的词汇,尤其是从UI角度的解释。为了更好的解释这个,我们先从一个简单的案例开始。

假设有个通信管道,每次通信前,你都需要先建立连接,然后发送数据,最后关闭连接。如果你有很多信息需要发送,你需要重复多次这些步骤,这些步骤都需要很多的开销。但是,所谓的事务就是你只建立一次连接,然后把所有消息一次性都发送过去,最后关闭连接即可。

我们在把这个过程更泛化下,可以把‘发送信息’认为一次你想做的操作,‘建立/关闭’连接对应于执行一次操作的‘前置/后置‘条件。然后,你可以多带带定义建立/关闭标志,然后在任何方法中使用他们(我们可以把这些建立/关闭标志称为包装器(wrappers),因为每个包装器都会包装某个动作方法)。

回到React,事务是React中广泛采用的一种模式。先不论包装行为,事务允许应用重置事务流,阻塞一个已经在执行过程中的同步方法等等。React中有很多不同的事务类,每个类都描述一种具体的行为,但是每个类都是继承自Transaction模块。每种事务对应的键值和特定的事务包装类是对应的。包装器就是一个拥有initialize方法和close方法的对象。

总之,大概的过程就是:

调用每个包装器的initialize方法,然后缓存其返回值

调用事务方法本身

调用包装器的close方法

来看些React中其它使用事务的场景:

保留输入框的选择范围,以便在同步Dom结构之前/之后,其实事件发送错误,依然能够恢复选择

在重排DOM防止失焦/聚焦时停止事件,确保重排之后,事件系统重新激活

在游览器的工作线程中发生同步Dom结构后,将收集到的DOM变化队列刷新到UI渲染主线程上

渲染新内容后,调用收集的componentDidUpdaate的回调函数。

了解以上内容后,回到我们一开始的实例代码。
从流程图中能看出,React调用了类ReactDefaultBatchingStrategyTransaction 。就像我们在上面的内容里所说的,一个事务类的关键是它的包装器。 所以,我们详细看下包装器,然后试着找出事务的精确定义。 两个包装器 FLUSH_BATCHED_UPDATES,RESET_BATCHED_UPDATES. 先看下源码:

//src
endererssharedstack
econcilerReactDefaultBatchingStrategy.js#19
var RESET_BATCHED_UPDATES = {
      initialize: emptyFunction,
      close: function() {
        ReactDefaultBatchingStrategy.isBatchingUpdates = false;
      },
};

var FLUSH_BATCHED_UPDATES = {
     initialize: emptyFunction,
     close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates),
}

var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];

正如你所见,这个事务类没有先置条件。initialize方法是个空方法,但其中有个close方法--ReactUpdates.flushBatchedUpdates却值得注意。它的作用是,
在以后的重新渲染中开始脏组件的验证过程。我们调用挂载方法,并把它包装进这个事务中,这是为了在挂载动作后,React会检查已挂载组件影响到了哪些内容,并更新这些内容。
再看下流程图里被包装进事务的方法,事实上,这个方法会调用另外一个事务。。。
(未完待续)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95751.html

相关文章

  • Under-the-hood-ReactJS-Part6】React源码解读

    摘要:源码里有个独立的模块管理组件的所有子元素。第一个,实例化子元素使用并挂载它们。至于具体挂载流程,基于子元素类型的不同而有不同的挂载过程。挂载的过程基本完成了。 接上文, React流程图:https://bogdan-lyashenko.gith... 创建初始子组件 在之前的步骤里,组件本身的构建已经完成,接下去,我们分析它们的子元素。总共分为两步:挂载子元素(this.mountC...

    codergarden 评论0 收藏0
  • Under-the-hood-ReactJS-Part9】React源码解读

    摘要:当鼠标事件发生时,组件的最外层会进行处理,然后通过几层包装器的处理后,会开始进行批量更新操作。在这之后,会将这些事件处理成常见到样子。 接上文, React流程图:https://bogdan-lyashenko.gith... 回到最初 在流程图中,也许你已经注意到,setState方法可以通过几种方式触发,更准确的说,可以分为是否由外部引起的(也就是是否由用户触发)。让我们看下如下...

    SnaiLiu 评论0 收藏0
  • Under-the-hood-ReactJS-Part11React源码解读

    摘要:技术上来说,当方法被调用后或者发生改变后,方法都会被调用。下一步,会设置为。之后,检测当前更新是否由更新引起的。这是因为,使用是导致组件持久化更新,而会被方法的返回值重新赋值。 接上文, React流程图:https://bogdan-lyashenko.gith... 更新组件 关于组件的更新,我们先看下代码里的注释: 对于已挂载组件的更新过程,React会首先调用component...

    hiyayiji 评论0 收藏0
  • Under-the-hood-ReactJS-Part8】React源码解读

    摘要:接上文,流程图我们已经知道挂载的工作流程,现在我们换个方向研究下方法,这个也是的重要组成部分。这个问题,我们会在下一篇文章中进行解答。。。 接上文, React流程图:https://bogdan-lyashenko.gith... this.setState 我们已经知道挂载的工作流程,现在我们换个方向研究下--setState方法,这个也是React的重要组成部分。 首先,为什么我...

    zhoutk 评论0 收藏0
  • Under-the-hood-ReactJS-Part13】React源码解读

    摘要:接着,将返回的元素和之前的进行比较的,以验证是否真的需要更新。我们看下代码,代码比较简单好,对应于我们的这个列子,我们对于方法的更改并不会对方法造成影响。所以我们进入下一步,也就是对于节点的更新。 接上文, React流程图:https://bogdan-lyashenko.gith... 如果组件真的需要更新 在组件刚开始更新过程时,如果有定义componentWillUpdate方...

    jerryloveemily 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<