Skip to content
On this page

completeWork

由于 render 过程其实属于 DFS(深度优先)过程,因此第一个触发 completeWork的顺序是子节点到父节点

js
function completeWork(current, workInProgress) {
	//...
	switch (workInProgress.tag) {
		// 子节点(可能是文本节点,也可能是html节点或其他)
		// ...
		case HostComponent: // html
			// 首屏渲染逻辑
			// 1. 创建 dom 节点
			const instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
			// 2. 挂载 workInProgress 的 子节点
      appendAllChildren(instance, workInProgress, false, false);
      // 3. 首屏渲染的dom节点赋值到 workInProgress(当前FiberNode)的 stateNode
      workInProgress.stateNode = instance;
      if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {
        markUpdate(workInProgress);
      }
	}
}

createInstance

负责创建dom节点

js
function createInstance(type, props, rootInstance) {
	// ... domElemenet 就是通过 document.createElement 生成的 dom 节点
	const domElement: Instance = createElement(type, props, rootContainerInstance, parentNamespace);
	return domElement // 返回给上层使用
}

appendAllChildren

负责挂载 workInProgress 的子节点

js

appendAllChildren = function (parent, workInProgress) {
    let node = workInProgress.child;
    // 循环将子节点列表的 dom 全部挂载
    while (node !== null) {
      if (node.tag === HostComponent || node.tag === HostText) {
        appendInitialChild(parent, node.stateNode);
      } else if (node.tag === HostPortal) ; else if (node.child !== null) {
        //...
      }

      if (node === workInProgress) {
        return;
      }

      while (node.sibling === null) {
        if (node.return === null || node.return === workInProgress) {
          return;
        }

        node = node.return;
      }

      node.sibling.return = node.return;
      node = node.sibling;
    }
};

如何挂载到页面上

FiberRootNodereconcileChildren 的 分支过程中(参考2-1),会在 placeSingleChild 赋值 App 节点 flags = Placement(2)

js
function placeSingleChild(newFiber) {
		// 首屏渲染,App FiberNode没有alternate,因此 flags 标记 Placement
	if (shouldTrackSideEffects && newFiber.alternate === null) {
		newFiber.flags |= Placement;
	}
	return newFiber;
}

function performSyncWorkOnRoot() {
	// ...
	// finishedWork 本次更新生成的 FiberNode 树,里面包含完整的 DOM 树
	const finishedWork = root.current.alternate;
  root.finishedWork = finishedWork;
  root.finishedLanes = lanes;
  // commit 挂载 DOM 到页面
  commitRoot(root);
}