React源码-commitRoot

241 阅读2分钟

在React中,commitRoot是一个非常重要的函数,它主要进行以下操作:

  1. 首先,它会获取当前的更新队列,这是一个保存了所有需要更新的组件的队列。
  2. 然后,它会根据更新队列中每个组件的更新类型,将这些组件分成不同的列表。这些更新类型包括插入、更新和删除。
  3. 接下来,对于每个需要插入的组件,commitRoot会调用ReactDOM的createInstance函数来创建组件的实例,并将其插入到DOM中。
  4. 对于需要更新的组件,commitRoot会调用ReactDOM的updateInstance函数来更新组件的属性和状态,并更新DOM。
  5. 最后,对于需要删除的组件,commitRoot会调用ReactDOM的deleteInstance函数来删除组件的实例,并从DOM中移除对应的节点。
function commitRoot(root) {
  const previousUpdatePriority = getCurrentUpdatePriority();
  try {
    //把当前的更新优先级设置为1
    setCurrentUpdatePriority(DiscreteEventPriority);
    commitRootImpl(root)
  } finally {
    setCurrentUpdatePriority(previousUpdatePriority);
  }
}
function commitRootImpl(root) {
  //先获取新的构建好的fiber树的根fiber tag=3
  const { finishedWork } = root;
  console.log('commit', finishedWork.child.memoizedState.memoizedState[0]);
  workInProgressRoot = null;
  workInProgressRootRenderLanes = NoLanes;
  root.callbackNode = null;
  root.callbackPriority = NoLane;
  //合并统计当前新的根上剩下的车道
  const remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);
  markRootFinished(root, remainingLanes);
  if ((finishedWork.subtreeFlags & Passive) !== NoFlags
    || (finishedWork.flags & Passive) !== NoFlags) {
    if (!rootDoesHavePassiveEffect) {
      rootDoesHavePassiveEffect = true;
      Scheduler_scheduleCallback(NormalSchedulerPriority, flushPassiveEffect);
    }
  }
  //判断子树有没有副作用
  const subtreeHasEffects = (finishedWork.subtreeFlags & MutationMask) !== NoFlags;
  const rootHasEffect = (finishedWork.flags & MutationMask) !== NoFlags;
  //如果自己的副作用或者子节点有副作用就进行提交DOM操作
  if (subtreeHasEffects || rootHasEffect) {
    //当DOM执行变更之后
    commitMutationEffectsOnFiber(finishedWork, root);
    //执行layout Effect
    commitLayoutEffects(finishedWork, root);
    if (rootDoesHavePassiveEffect) {
      rootDoesHavePassiveEffect = false;
      rootWithPendingPassiveEffects = root;
    }
  }
  //等DOM变更后,就可以把让root的current指向新的fiber树
  root.current = finishedWork;
  //在提交之后,因为根上可能会有跳过的更新,所以需要重新再次调度
  ensureRootIsScheduled(root, now());
}

总之,commitRoot是React更新DOM的核心函数之一,它通过对更新队列中每个组件的更新类型进行分析,并调用相应的函数来完成DOM的更新和渲染。

此外,commitRoot函数还会触发一些React的生命周期方法,如componentDidMount、componentDidUpdate和componentWillUnmount等,以便在组件更新和渲染时执行一些必要的操作。

需要注意的是,commitRoot函数不是同步执行的,它会将所有的DOM更新操作都放在一个队列中进行异步更新,以便提高性能和减少页面的重绘次数。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第7天,点击查看活动详情