博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Under-the-hood-ReactJS-Part10】React源码解读
阅读量:7144 次
发布时间:2019-06-29

本文共 2253 字,大约阅读时间需要 7 分钟。

接上文,

React流程图:

‘脏’组件

从流程图里能看出,React会遍历dirtyComponents数组,并在事务中调用ReactUpdates.runBatchedUpdates。这个事务是个新事务。那么为什么要这么设计呢?

此事务的类型为ReactUpdatesFlushTransaction,在此之前我们已经提到过,我们去看下其相应的包装器以方便我们理解这个事务具体完成什么任务。代码里有如下注释:

ReactUpdatesFlushTransaction包装器会清空dirtyComponents数组,并且执行所有已经压入队列里的更新操作,这些操作一般都是由过程后的处理方法压入的(比如,commponentDidUpdate方法)(ReactUpdatesFlushTransaction’s wrappers will clear the dirtyComponents array and perform any updates enqueued by mount-ready handlers (i.e., componentDidUpdate))

我们也验证下是否代码真的这样运转。该事务有两个包装器,NEST_UPDATES和UPDATE_QUEUEING。在事务的初始化阶段,我们会先把dirtyComponentsLength存储起来,然后在关闭阶段,React进行组件比较。在更新过程中,很可能dirtyComponents组件都发生里改变,所以,需要不止一次的运行flushBatchedUpdates方法。代码比较直白,没有什么黑魔法。

但是,这里其实有个地方需要注意下,ReactUpdatesFlushTransaction覆盖了Transaction.perform方法,之所以这么做,是因为,执行更新时需要调用ReactReconcileTransacation里的行为(这个事务在挂载过程中也使用到了,目的是为了确保应用状态安全)。所以,在ReactUpdatesFlushTransaction.perform方法的执行过程中,ReactReconcileTransaction方法会被调用到,所以,就是把事务方法在包了一次。

整个技术流程大概如此:

[NESTED_UPDATES, UPDATE_QUEUEING].initialize()[SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING].initialize()method -> ReactUpdates.runBatchedUpdates[SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING].close()[NESTED_UPDATES, UPDATE_QUEUEING].close()

在此文的最后,我们会回到事务方法,在确认下事务是如何帮助方法完成的,但在此之前,我们先确认下ReactUpdates.runBatchedUpdates的实现。(srcrendererssharedstackreconcilerReactUpdates.js#125)

在执行之前的第一步,就是把dirtyComponets进行排序,如何排序呢?基于mount order这个字段进行排序(一个整数值,在组件实例化时被设置进组件),这个字段代表父组件(它们也最先挂载)先更新,子组件接下去更新,以此类推。下一步,React会对updateBatchNumber加1操作,这个字段类似于当前处理DOM的ID,看下代码里的注释,看下代码里的注释:

在更新过程中加入队列的更新必须在批量操作执行完后再执行。否则,假设dirtyComponents为有组件A,B,其中A的子组件为B,B有子组件C,如果C有更新,则B将再次被压入队列,导致B被更新两次。对于这种情况,我们只能通过检查批量更新的计数器来跳过这次更新。(‘Any updates enqueued while reconciling must be performed after this entire batch. Otherwise, if dirtyComponents is [A, B] where A has children B and C, B could update twice in a single batch if C’s render enqueues an update to B (since B would have already updated, we should skip it, and the only way we can know to do so is by checking the batch counter).’)

这个设计避免了同一个组件的重复更新。

最后,我们遍历完整个dirtyComponents队列,然后把每个组件传递给了ReactReconciler.performUpdateIfNecessary,这个方法会在ReactCompisteCompoent里被调用,所以,最终我们又回到了ReactCompsiteComponet里的updateComponet方法。现在,我们可以更深入的研究下这个方法。

(未完待续)

转载地址:http://xpwgl.baihongyu.com/

你可能感兴趣的文章
让IE和Chrome都以隐身模式启动
查看>>
MyPython-->进阶篇-->类
查看>>
unity remote 连接设置
查看>>
2018 NOIP备战计划
查看>>
教你如何迅速秒杀掉:99%的海量数据处理面试题
查看>>
zw版【转发·台湾nvp系列Delphi例程】HALCON InpaintingCt2
查看>>
POJ2155 Matrix
查看>>
字符串匹配算法
查看>>
Eclipse 问题整理
查看>>
Java常用工具类之RegexpUtils,正则表达式工具类
查看>>
c# 利用反射 从json字符串 动态创建类的实例 并动态为实例成员赋值
查看>>
Kali Linux 优化过程
查看>>
关于图片处理的方法整理
查看>>
手机短信猫
查看>>
JavaScript DOM对象
查看>>
裸机恢复 (BMR) 和系统状态恢复
查看>>
IE自动化 二(判断IP所在地)
查看>>
select下拉框多选 和回显
查看>>
苹果允许Flash程序在iPad和iPhone中使用
查看>>
一起谈.NET技术,XML与DataSet对象的关系
查看>>