React源码解析:简述React 16 版本中 commit 阶段的三个子阶段分别做了那些事?

(1)before mutation阶段(执行DOM操作前):处理类组件的getSnapShotBeforeUpdate 生命周期函数

  1. 处理DOM节点渲染/删除后的 autoFocus、blur逻辑;
  2. 调用getSnapshotBeforeUpdate生命周期钩子;
  3. 调度useEffect。

(2)mutation阶段(执行DOM操作):将 workInProgress Fiber 树变成 current Fiber 树

  • 如果该fiber类型是ClassComponent的话,执行getSnapshotBeforeUpdate生命周期api,将返回的值赋到fiber对象的__reactInternalSnapshotBeforeUpdate上;
  • 如果该fiber类型是FunctionComponent的话,执行hooks上的effect相关 API。

代码层面:

  1. 根据ContentReset effectTag重置文字节点;
  2. 更新ref;
  3. 根据effectTag分别处理,其中effectTag包括(Placement | Update | Deletion | Hydrating);
  4. Placement时:获取父级DOM节点。其中finishedWork为传入的Fiber节点获取Fiber节点的DOM兄弟节点根据DOM兄弟节点是否存在决定调用parentNode.insertBefore或parentNode.appendChild执行DOM插入操作;
  5. Update时:执行所有useLayoutEffect hook的销毁函数。调用commitWork;6.Deletion时:递归调用Fiber节点及其子孙Fiber节点中fiber.tag为ClassComponent的componentWillUnmount
    (opens new window)生命周期钩子,从页面移除Fiber节点对应DOM节点解绑ref调度useEffect的销毁函数。

(3)layout(执行 DOM 操作后):commitHookEffectList()阶段,调用类组件生命周期函数或者函数组件的钩子函数

重置 nextEffect,useEffect是让FunctionComponent产生副作用的hooks,当使用useEffect后,会在fiber上的updateQueue.lastEffect生成effect链,具体请看ReactFiberHooks.js中的pushEffect()

作用:循环FunctionComponent上的effect链,并根据每个effect上的effectTag,执行destroy/create操作(作用类似于componentDidMount/componentWillUnmount)

代码层面:

  1. 调用componentDidxxx;
  2. 调用this.setState第二个参数回调函数;
  3. 调用useLayoutEffect hook的回调函数(与mutation的销毁函数是同步的),调度useEffect的销毁与回调函数(在before
    mutation只是先调度加入异步任务,在这里才真正执行),因此useLayoutEffect是同步的,useEffect是异步的;
  4. 获取DOM实例,更新ref5.current Fiber树切换(workInProgress Fiber树在commit阶段完成渲染后会变为current Fiber树)。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值