【React】版本18 源码遨游(五) createRoot() updateContainer()

本文深入探讨了React 18中createRoot()和updateContainer()的源码,包括requestUpdateLane()、createUpdate()、enqueueUpdate()等关键过程,以及交错更新的处理策略。文章总结了在更新Container时的步骤,为理解React更新流程提供了详细指导。
摘要由CSDN通过智能技术生成

React DOM createRoot() updateContainer()

在v18.0之后,DOM.render()方法已经被归为Legacy,取而代之的是DOM.createRoot()方法。

位置:react-reconciler\src\ReactFiberReconciler.new.js

createRoot()

export function createRoot(
  container: Container,
  options?: CreateRootOptions,
): RootType {
   
  // 判断container有效性
  invariant(
    isValidContainerLegacy(container),
    'createRoot(...): Target container is not a DOM element.',
  );
  warnIfReactDOMContainerInDEV(container);

  // 下述注水相关可选项会在未来被删除...
  // 注水可选项
  const hydrate = options != null && options.hydrate === true;
  // 注水是否有回调
  const hydrationCallbacks =
    (options != null && options.hydrationOptions) || null;
  // 可更改sources
  const mutableSources =
    (options != null &&
      options.hydrationOptions != null &&
      options.hydrationOptions.mutableSources) ||
    null;

  // 严格模式flag
  const isStrictMode = options != null && options.unstable_strictMode === true;
  // 默认同步更新,null
  let concurrentUpdatesByDefaultOverride = null;
  if (allowConcurrentByDefault) {
   
    concurrentUpdatesByDefaultOverride =
      options != null && options.unstable_concurrentUpdatesByDefault != null
        ? options.unstable_concurrentUpdatesByDefault
        : null;
  }

  // createContainer 创建一个FiberRoot,每个属性的意义可以参考上一篇文章
  const root = createContainer(
    container,
    ConcurrentRoot,
    hydrate,
    hydrationCallbacks,
    isStrictMode,
    concurrentUpdatesByDefaultOverride,
  );
  // 标记这个container为根,具体就是把这个container设置为内部实例key
  markContainerAsRoot(root.current, container);

  // 根container元素,要么是container本身要么是container的父节点
  const rootContainerElement =
    container.nodeType === COMMENT_NODE ? container.parentNode : container;
  // 给根container元素加上所有支持的事件监听
  listenToAllSupportedEvents(rootContainerElement);

  // 下述在未来会被删除...
  if (mutableSources) {
   
    for (let i = 0; i < mutableSources.length; i++) {
   
      const mutableSource = mutableSources[i];
      // 将所有可更改sources注册,即将所有可更改sources传入fiberRoot的mutableSourceEagerHydrationData数组中
      registerMutableSourceForHydration(root, mutableSource);
    }
  }

  // 将创建的root传入私有变量_internalRoot中并返回
  return new ReactDOMRoot(root);
}

updateContainer()

export function updateContainer(
  element: ReactNodeList,
  container: OpaqueRoot,
  parentComponent: ?React$Component<any, any>,
  callback: ?Function,
): Lane {
   
  if (__DEV__) {
   
    onScheduleRoot(container, element);
  }
  // 当前可更改的fibeRoot
  const current = container.current;
  // 保存事件的开始时间
  const eventTime = requestEventTime();
  // 请求一个更新车道lane,requestUpdateLane方法后续再考
  const lane = requestUpdateLane(current);	

  if (enableSchedulingProfiler) {
   
    // 在Performance接口中标记--schedule-render-{当前lane}用于性能分析
    markRenderScheduled(lane);
  }

  // 查找子树的context,如果当前fiberRoot没有context则赋值,如有则保存在pendingContext中
  const context = getContextForSubtree(parentComponent);
  if (container.context === null) {
   
    container.context = context;
  } else {
   
    container.pendingContext = context;
  }

  if (__DEV__) {
   
    if (
      ReactCurrentFiberIsRendering &&
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值