Skip to content

从零实现mini-react(3):统一提交&实现function component

统一提交

问题
当没有空闲时间时,会导致部分渲染部分没有渲染,可能导致用户看到部分被渲染的 dom 结构,即渲染不完全的问题


解决办法 处理节点的时候只是创建dom和更新dom的props,处理children逻辑,但不加载dom到父节点。统一提交后,所有的 dom 都创建完成后再统一挂载渲染。

javascript
function commitRoot() {
  commitWork(root.child);
  root = null;
}

function commitWork(fiber) {
  if (!fiber) return;

  let fiberParent = fiber.parent;
  while (!fiberParent.dom) {
    fiberParent = fiberParent.parent;
  }

  if (fiber.dom) {
    fiberParent.dom.append(fiber.dom);
  }

  commitWork(fiber.child);
  commitWork(fiber.sibling);
}

支持function component

  • 实现Function Component
    • 函数生成dom,并且可以传入props
    • 实际上就是比普通的component多了一层拆包的过程,判断fiber的type是否为函数,然后进一步去拆包。
    • 由于function component 本身没有vdom,在寻找父容器和兄弟节点时,需要采用循环向上的方式。
    • 需要考虑到多种边缘情况
javascript
function performWorkOfUnit(fiber) {
  const isFunctionComponent = typeof fiber.type === "function";

  if (isFunctionComponent) {
    updateFunctionComponent(fiber);
  } else {
    updateHostComponent(fiber);
  }

  //...
}

function createElement(type, props, ...children) {
  return {
    type,
    props: {
      ...props,
      children: children.map((child) => {
        const isTextNode =
          typeof child === "string" || typeof child === "number";
        return isTextNode ? createTextNode(child) : child;
      }),
    },
  };
}