react源码解析10.commit阶段

react源码解析10.commit阶段

视频讲解(高效学习):进入学习
往期文章:

1.开篇介绍和面试题

2.react的设计理念

3.react源码架构

4.源码目录结构和调试

5.jsx&核心api

6.legacy和concurrent模式入口函数

7.Fiber架构

8.render阶段

9.diff算法

10.commit阶段

11.生命周期

12.状态更新流程

13.hooks源码

14.手写hooks

15.scheduler&Lane

16.concurrent模式

17.context

18事件系统

19.手写迷你版react

20.总结&第一章的面试题解答

21.demo

在render阶段的末尾会调用commitRoot(root);进入commit阶段,这里的root指的就是fiberRoot,然后会遍历render阶段生成的effectList,effectList上的Fiber节点保存着对应的props变化。之后会遍历effectList进行对应的dom操作和生命周期、hooks回调或销毁函数,各个函数做的事情如下

react源码10.1

在commitRoot函数中其实是调度了commitRootImpl函数

//ReactFiberWorkLoop.old.js
function commitRoot(root) {
   
  var renderPriorityLevel = getCurrentPriorityLevel();
  runWithPriority$1(ImmediatePriority$1, commitRootImpl.bind(null, root, renderPriorityLevel));
  return null;
}

在commitRootImpl的函数中主要分三个部分:

  • commit阶段前置工作

    1. 调用flushPassiveEffects执行完所有effect的任务

    2. 初始化相关变量

    3. 赋值firstEffect给后面遍历effectList用

      //ReactFiberWorkLoop.old.js
      do {
             
          // 调用flushPassiveEffects执行完所有effect的任务
          flushPassiveEffects();
        } while (rootWithPendingPassiveEffects !== null);
      
      	//...
      
        // 重置变量 finishedWork指rooFiber
        root.finishedWork = null;
      	//重置优先级
        root.finishedLanes = NoLanes;
      
        // Scheduler回调函数重置
        root.callbackNode = null;
        root.callbackId = NoLanes;
      
        // 重置全局变量
        if (root === workInProgressRoot) {
             
          workInProgressRoot = null;
          workInProgress = null;
          workInProgressRootRenderLanes = NoLanes;
        } else {
             
        }
      
       	//rootFiber可能会有新的副作用 将它也加入到effectLis
        let firstEffect;
        if (finishedWork.effectTag > PerformedWork) {
             
          if (finishedWork.lastEffect !== null) {
             
            finishedWork.lastEffect.nextEffect = finishedWork;
            firstEffect = finishedWork.firstEffect;
          } else {
             
            firstEffect = finishedWork;
          }
        } else {
             
          firstEffect = finishedWork.firstEffect;
        }
      
  • mutation阶段

    ​ 遍历effectList分别执行三个方法commitBeforeMutationEffects、commitMutationEffects、commitLayoutEffects执行对应的dom操作和生命周期

    ​ 在介绍双缓存Fiber树的时候,我们在构建完workInProgress Fiber树之后会将fiberRoot的current指向workInProgress Fiber,让workInProgress Fiber成为current,这个步骤发生在commitMutationEffects函数执行之后,commitLayoutEffects之前,因为componentWillUnmount发生在commitMutationEffects函数中,这时还可以获取之前的Update,而componentDidMountcomponentDidUpdate会在commitLayoutEffects中执行,这时已经可以获取更新后的真实dom了

    function commitRootImpl(root, renderPriorityLevel) {
         
    	//...
    	do {
         
          //...
          commitBeforeMutationEffects();
        } while (nextEffect !== null);
      
    	do {
         
          //...
          commitMutationEffects(root, renderPriorityLevel);//commitMutationEffects
        } while (nextEffect !== null);
      
      root.current = finishedWork;//切换current Fiber树
      
      do {
         
          //...
          commitLayoutEffects(root, lanes);//commitLayoutEffects
        } while (nextEffect 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值