资讯专栏INFORMATION COLUMN

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

AndroidTraveler / 1301人阅读

摘要:下面是源码里的注释发现属性差异后进行合并,并且在需要时进行更新。在这里会进行两次循环。注意,在整个应用的运行过程中,所有的事件都是通过名为合成事件的东西进行传递的。它包含了一个名为的对象进行监听器的缓存和光临。

接上文,

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

更新DOM属性

在更新DOM属性这一步,主要的目标就是将之前的props和当前props的差异高效的更新到DOM上。下面是源码里的注释:

发现属性差异后进行合并,并且在需要时进行DOM更新。这个方法很可能是性能优化的路径上的最关键的单一方法。(“Reconciles the properties by detecting differences in property values and updating the DOM as necessary. This function is probably the single most critical path for performance optimization.”)

在这里会进行两次循环。第一次,遍历上一次的props,然后再遍历下一次的props。
在我们的案例中,挂载时,lastProps(上一次的属性)是空值(因为这是我们第一次进行赋值),不过,我们还是可以看看里面发生了什么

循环前props

在这个循环的第一步中,我们会检查nextProps是否包含相同的属性值。如果有的话,对于这些属性值我们会先跳过,因为它们会在之后的nextprops循环中被处理掉。然后,我们会重置样式,删除事件监听器(如果之前有设置的话),移除DOM属性和DOM属性值。对于属性的处理,我们需要确保它们不是RESERVED_PROPS中的保留关键字,那些是真正的组件属性,如children,dangerouslySetInnerHTML。

循环后props

在这个循环的第一步中,首先需要检查prop是否改变了,也就是检查属性的下一个值是否和之前的不同。如果是相同的话,则什么都不需要做。对于样式(你应该发现对于样式的处理有些特殊),如果根lastProp相比有变化的,React会更新其值。然后,添加会事件监听器(就像onClick等等)。下面,我们进一步的进行分析。

注意,在整个React应用的运行过程中,所有的事件都是通过名为合成事件(synthetic events)的东西进行传递的。所谓的合成事件,就是为了更高效的使React工作而组装的一些包装器。而管理事件的中介模块就是就是EventPuginHub(srcrendererssharedstackeventEventPluginHub.js)。它包含了一个名为listenerBank的map对象进行监听器的缓存和光临。我们需要把我们的事件监听器加入其中,不过不是现在,而是在组件和DOM元素已经准备好处理事件的时候。在这里,看起来好像我们延迟了事件的执行,你可以会问,我们如何获知事件发生的那一刻呢?不知道你是否还记得我们会在所有的方法调用里传递transaction这个事务对象,之所以这样做,就是为了让我们能够更方便的处理这种上面疑问的场景,看下代码:

//src
enderersdomsharedReactDOMComponent.js#222
transaction.getReactMountReady().enqueue(putListener, {
    inst: inst,
    registrationName: registrationName,
    listener: listener,
});

在处理完事件监听器后,我们需要设置DOM属性和属性值。就像上面说的那样,我们需要确保这些属性不是RESEVED_PROPS的保留关键字,那些是真正的组件属性,如children和djangerouslySetInnerHTML。

在处理属性的前后差异过程中,我们会计算出styleUpdates的配置,然后把它传递给CSSPropertyOperations模块。

现在,我们已经完成对属性更新的过程的分析,我们可以继续下一步了。
(未完待续)

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

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

相关文章

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

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

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

    摘要:技术上来说,当方法被调用后或者发生改变后,方法都会被调用。下一步,会设置为。之后,检测当前更新是否由更新引起的。这是因为,使用是导致组件持久化更新,而会被方法的返回值重新赋值。 接上文, 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-Part9】React源码解读

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

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

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

    jerryloveemily 评论0 收藏0

发表评论

0条评论

AndroidTraveler

|高级讲师

TA的文章

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