React18 阅读笔记 -- completeWork

115 阅读1分钟

completeWork

根据 workInProgress.tag 找到需要创建/更新 dom 的 tag,根据 fiber 创建/更新 dom

// path: packages/react-reconciler/src/ReactFiberCompleteWork.old.js
function completeWork(
  current: Fiber | null,
  workInProgress: Fiber,
  renderLanes: Lanes
): Fiber | null {
  switch (workInProgress.tag) {
    case IndeterminateComponent:
    case LazyComponent:
    case SimpleMemoComponent:
    case FunctionComponent:
    case ForwardRef:
    case Fragment:
    case Mode:
    case Profiler:
    case ContextConsumer:
    case MemoComponent:
      bubbleProperties(workInProgress);
      return null;
    case HostText: {
      // ...省略部分代码
      // 根据不同tag 为 stateNode 创建 对应dom 节点
      workInProgress.stateNode = createTextInstance(
        newText,
        rootContainerInstance, // root
        currentHostContext,
        workInProgress
      );
      // 将所有child 的 return赋值为 completedWork;
      // 计算 completedWork 的 subtreeFlags
      bubbleProperties(workInProgress);
      return null;
    }
    case HostComponent: {
      // 将当前 fiber 移出 fiberStack
      popHostContext(workInProgress);
      // 在beginWork中对于HostRoot和HostPortal节点都会将真实节点container全
      // 局存储到rootInstanceStackCursor.current,而在completeWork阶段将其移出。
      // 在访问子节点时就能正确获取到它所在的容器
      // 获取的是当前的 RootHostContainer
      const rootContainerInstance = getRootHostContainer();
      const type = workInProgress.type;
      if (current !== null && workInProgress.stateNode != null) {
        // // 如果真实节点存在,那么进行更新
        updateHostComponent(
          current,
          workInProgress,
          type,
          newProps,
          rootContainerInstance
        );
      } else {
        if (!newProps) {
          bubbleProperties(workInProgress);
          return null;
        }

        const currentHostContext = getHostContext();

        const instance = createInstance(
          type,
          newProps,
          rootContainerInstance,
          currentHostContext,
          workInProgress
        );
        // 将能渲染的子节点全部添加到当前创建的节点instance上
        appendAllChildren(instance, workInProgress, false, false);

        workInProgress.stateNode = instance;
      }
      bubbleProperties(workInProgress);
      return null;
    }
  }
}

HostComponent

root 根节点 进如的 case

export function updateHostComponent() {
  // ...

  // 类似结构:['name', '张三', 'id', 333, 'style', { color: 'red' }]
  const updatePayload = prepareUpdate(
    instance,
    type,
    oldProps,
    newProps,
    rootContainerInstance,
    currentHostContext,
  );
  workInProgress.updateQueue = (updatePayload: any);
  // 标记为 Update
  if (updatePayload) {
    markUpdate(workInProgress);
  }
};

export function createInstance(
  type: string,
  props: Props,
  rootContainerInstance: Container,
  hostContext: HostContext,
  internalInstanceHandle: Object
): Instance {
  // 创建了 element
  const domElement: Instance = createElement(
    type,
    props,
    rootContainerInstance,
    parentNamespace
  );
  // 建立关系 node . '__reactFiber$' + randomKey = fiber
  precacheFiberNode(internalInstanceHandle, domElement);
  // 建立关系 node . '__reactProps$' + randomKey = props
  updateFiberProps(domElement, props);
  return domElement;
}