Skip to content

03.单节点 domdiff

js
/**
 * 使用现有的fiber节点和待处理的props创建新的fiber节点
 * @param {Object} fiber 现有的fiber节点
 * @param {Object} pendingProps 待处理的props
 * @return {Object} clone 新的fiber节点
 */
function useFiber(fiber, pendingProps) {
  const clone = createWorkInProgress(fiber, pendingProps);
  clone.index = 0;
  clone.sibling = null;
  return clone;
}
/**
 * 将子节点添加到待删除列表中
 * @param {Object} returnFiber 父级fiber节点
 * @param {Object} childToDelete 需要被删除的子fiber节点
 */
function deleteChild(returnFiber, childToDelete) {
  if (!shouldTrackSideEffects) return;
  const deletions = returnFiber.deletions;
  if (deletions === null) {
    returnFiber.deletions = [childToDelete];
    returnFiber.flags |= ChildDeletion;
  } else {
    returnFiber.deletions.push(childToDelete);
  }
}

/**
 * 删除所有剩余的子节点
 * @param {Object} returnFiber 父级fiber节点
 * @param {Object} currentFirstChild 当前的第一个子节点
 * @return {null} 返回null
 */
function deleteRemainingChildren(returnFiber, currentFirstChild) {
  if (!shouldTrackSideEffects) return;
  let childToDelete = currentFirstChild;
  while (childToDelete !== null) {
    deleteChild(returnFiber, childToDelete);
    childToDelete = childToDelete.sibling;
  }
  return null;
}
function reconcileSingleElement(returnFiber, currentFirstChild, element) {
  const key = element.key;
  let child = currentFirstChild;
  while (child !== null) {
    if (child.key === key) {
      if (child.type === element.type) {
        deleteRemainingChildren(returnFiber, child.sibling);
        const existing = useFiber(child, element.props);
        existing.return = returnFiber;
        return existing;
      } else {
        deleteRemainingChildren(returnFiber, child);
      }
    } else {
      deleteChild(returnFiber, child);
    }
    child = child.sibling;
  }

  const created = createFiberFromElement(element);
  created.return = returnFiber;
  return created;
}

基于 VitePress 构建