React 执行架构流程详细----递阶段 mount 时流程(二)

React 执行架构流程详细----递阶段 mount 时流程(二)


引言

上一篇中了解到:

  • render 阶段开始于 renderRootSync,commit 阶段开始于 commitRoot

  • render 阶段使用遍历来实现了可中断的递归,其中递归可以分为 递阶段和归阶段

  • 递阶段就是执行的 beginWork,归阶段就是执行的 completeWork

  • render 阶段不会执行具体的dom操作,具体的dom操作是在commit 阶段执行,render阶段需要做的就是为需要执行的dom操作的 fiber 节点打上标记,若节点需要插入在页面中,就打上 Placement 标记;若节点需要删除,就打上 deletion的标记

    在这里插入图片描述


四个阶段

在阐述双缓存机制时了解到,在 mount时,不存在对应的 currentFiber 树,而在 update 时,存在一棵 currentFiber 树,所以在 mount 和 update 时,beginWork 和 completeWork 的工作会有一些不同,所以就分为以下四种情况来阐述:
在这里插入图片描述


递阶段 mount 时流程

也就是 mount 时 beginwork 的过程

比如页面是以下结构:
在这里插入图片描述


原理就是 DFS ,执行的过程是:
在这里插入图片描述

render 阶段完成之后,然后就进入了 commit 阶段

PSreact 对于 只有唯一文本子节点的节点 会做一个优化处理,比如 上面的 code 标签节点,这种文本节点不会生成自己的 fiber 节点,所以就没有该文本节点的 beginwork 和 completework的过程


beginWork 函数解析

举个🌰:

比如 以 div 标签的 beginWork 和 completeWork 来举例子:
在这里插入图片描述

  1. beginWork 首先会根据当前 workInProgress.tag 的类型来进入不同的 case
    在这里插入图片描述
    由于 div 属于 host component ,所以就进入 updateHostComponent 的逻辑
    在这里插入图片描述

  2. 在 updateHostComponent 中,首先会赋值一些变量,注意 isDirectTextChild 变量就是判断 该节点是否是子节点只含有文本节点,若是这种情况的话,会有优化
    在这里插入图片描述
  3. 之后会进入 reconcileChildren 函数:
    在这里插入图片描述
    在这里插入图片描述
  4. reconcileChildFibers 会判断当前 child 的类型,进入不同的处理逻辑,最后通过 react element 的属性等进而创建不同的 fiber 节点
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  5. reconcileChildFibers 和 mountChildFibers 函数的区别
    在这里插入图片描述
    进入 mountChildFibers 函数中创建的 fiber 节点,他是不会被标记的
    (详情请看下一篇

从这可以看出 reconcileChildFibers 和 mountChildFibers 函数的区别:
在这里插入图片描述

  1. 具体看 ChildReconciler 函数:这个 boolean 值就是 是否追踪副作用,从下面的来看,在 deleteChild 中,如果不支持副作用,则直接 return;如果要追踪副作用,会把 effectTag 打上 deletion 的标记;
    placeChild 类似,placeChild 代表需要将当前fiber节点对应的 dom 节点插入到页面中,如果不需要追踪副作用,就直接 return;若需要追踪副作用,会为这个fiber节点的 effectTag 打上 Placement 的标记
    在这里插入图片描述
    在这里插入图片描述
  2. 看具体的副作用的定义
    在这里插入图片描述
    使用二进制来定义副作用的原因是:
    举个🌰:
    若一个 fiber 节点(对应一个dom节点),首先需要插入到页面中,之后需要更新它的属性,所以就会同时存在 placement 和 update 两种 effectTag,即一个节点先 placement,再 update(即进行多次副作用的处理),在这种情况下,使用二进制非常方便就能实现这些功能,通过 按位或,按位与等操作来实现
    在这里插入图片描述
    使用按位或、按位与的操作易于实现存在多种 effectTag 标记

总结

执行栈:
在这里插入图片描述


当某一个 fiber 节点进入 beginWork 时,他最终的目的是为了创建当前fiber 节点的一个子fiber节点:
  1. 首先会判断当前fiber节点的类型,进入不同的 update 的逻辑;
  2. 在 update 的逻辑中,他会判断当前的workInProgress fiber 中是否存在对应的 current fiber,来决定是否标记 effectTag
  3. 接着,会借助 reconciler 的逻辑,在 reconciler 中,会判断当前 fiber 节点的 children是什么类型,来执行不同的创建操作(比如是div节点,属于 hostComponent,是一个单一的 ReactElement 的type,所以会进入 reconcileSingleElement 函数)
  4. 最终会创建一个 子fiber 节点

参考资料:
React 项目源码
技术揭秘
React 版本是17

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值