Skip to content

render&commit阶段

本篇文章是在文章+手写期间的思路总结,是为了辅助文章和手写的产物,可能与最终的实现有所差异,也有可能有部分误差,请结合文章和手写代码仔细甄别(因为我懒得改了=_=)

  • render阶段beginWork
    • 构建fiber
    • fiber父子关系的绑定
    • reconcileChildFibers()进行子节点的diff,因此需要FunctionComponent/ClassComponent进行渲染,才能拿到对应的children元素
  • render阶段completeWork:
    • 对于HostComponent进行处理:初始化instance + appendAllChildren()将所有子dom挂载在父dom上
    • 对于HostText进行处理:初始化文本DOM,然后进行更新
  • commit阶段:
    • 直接使用原生的方法,比如appendChild、deleteChild等操作DOM,由于组件已经在render阶段构建完成,因此这里直接appendChild(dom)即可
    • 调用对应的effect函数的里面的内容!也就是处理fiber.updateQueue的lastEffect等链表数据

初始化时,beginWork会阻止设置Placementflag,然后在completeWork会进行HostComponent的处理:初始化instance + appendAllChildren()将所有子dom挂载在父dom上

但是更新时,beginWork不会阻止Placementflag,然后在completeWork会进行HostComponent的处理:更新属性

beginWorkFunctionComponent/ClassComponent无论是首次渲染/渲染更新,都会触发!

render阶段

当前fiber与fiber.children之间的切换依赖completeUnitOfWork

  • beginWork
  • completeWork

beginWork

主要根据fiber.tag调用不同的方法进行处理,核心方法最终都会调用mountChildFibers进行children元素的对比

  • 能够复用的数据,打上可以复用的flag
  • 不能复用的数据,打上删除的flag
  • 新增的数据,打上新增或者移动的flag

最终构建出fiber树!并且fiber都打上了flags!

completeWork

主要根据fiber.tag调用不同的方法进行处理,大部分直接返回null + 没做什么处理

但是对于HostComponent来说,会初始化dom + appendAllChildren()将所有子dom挂载在父dom上

这个阶段会初始化所有fiber的stateNode,并且绑定它们之间的关系,但是root不会跟它们绑定!因为要等到commit阶段root才会跟它们绑定!

commit阶段

根据标签调整DOM之间的关系,该复用就复用、该插入就插入、该删除就删除、该新增就新增

最终将rootDom与这些dom关联起来,形成DOM树!