React 源码 - render、commit阶段

579 阅读1分钟

1、render 阶段

  • 创建 Fiber 节点树(采用深度优先遍历)
  • 挂载 Dom
  • 生成 effectList 的单向环状链表
beginWork
  • mount时:
    • 采用深度优先的方式遍历 "DOM树"
    • 根据tag不同,创建不同类型的Fiber
  • update时:Diff算法
    • 对比当前组件与该组件在上次更新时对应的Fiber节点
  • reconcileChildren
    • 挂载子组件时调用 mountChildFibers
    • 更新子组件时调用 reconcileChildFibers

image.png

completeWork
  • mount时:
    • Fiber节点生成对应的DOM节点
    • 把子孙DOM节点插入刚生成的DOM节点
    • update逻辑中的updateHostComponent类似的处理props的过程
  • upate时:主要是处理props
    • onClickonChange等回调函数的注册
    • 处理style prop
    • 处理DANGEROUSLY_SET_INNER_HTML prop
    • 处理children prop
  • effectList:
    • completeWork的上层函数completeUnitOfWork
    • 每个执行完completeWork且存在effectTagFiber节点
    • 被保存在一条被称为effectList的单向链表中

image.png

2、commit 阶段

  • 作用:执行 Effect 链表

  • 过程:useEffect、useLayoutEffect 不同阶段执行不同的函数

image.png

before mutation阶段(执行DOM操作前)
  • 变量赋值、状态重置
  • 处理DOM节点渲染/删除后的 autoFocusblur 逻辑
  • 调用getSnapshotBeforeUpdateuseEffect 生命周期函数
mutation阶段(执行DOM操作)
  • 遍历effectList,依次执行commitMutationEffects
  • 根据effectTag调用不同的处理函数处理Fiber(增、删、更)
layout阶段(执行DOM操作后)
  • 遍历effectList,依次执行 commitLayoutEffectOnFiber
  • 根据fiber.tag 不同类型的节点分别处理
    • ClassComponent: 触发this.setState第二个参数回调函数
    • FunctionComponent:
      • 调用useLayoutEffect hook回调函数
      • useEffect销毁回调函数
  • commitAttachRef
    • 获取DOM实例
    • 更新ref
  • current Fiber树切换