react Diff(1) 更新后为单节点

101 阅读1分钟

更新后为单节点

*   更新前为单节点
    A1 -> A2
    A1 -> B1
*   更新前为多节点
    A1B1 -> A1

只有在 keytype 相同时 才能复用当前节点 其他情况都不能复用

实现思路:

  • 找出比较节点的 keytype 相同则复用

  • 删除其他不能复用的兄弟节点 image.png

代码实现

// 单节点
function reconcilerSingleElement(
  returnFiber: FiberNode,
  currentFiber: FiberNode | null,
  element: ReactElementType
) {
  // 1. 查看是否可以复用fiber currentFiber 与 wip 的fiber 做对比
  const key = element.key;
  while (currentFiber !== null) {
    // update
    if (currentFiber.key === key) {
      // key 相同
      if (element.$$typeof === REACT_ELEMENT_TYPE) {
        if (currentFiber.type === element.type) {
          // 当前节点的key 与 type 相同
          // 复用 fiber
          const existing = useFiber(currentFiber, element.props);
          existing.return = returnFiber;
          // 当前节点可复用 删除剩下的兄弟节点
          deleteRemainingChildren(returnFiber, currentFiber.sibling);
          return existing;
        }
        // type 不同 说明没有可复用的节点 删除所有旧的节点
        deleteRemainingChildren(returnFiber, currentFiber);
        break;
      } else {
        if (__DEV__) {
          console.warn('还未实现的reconciler', element);
          break;
        }
      }
    } else {
      // key 不同删除当前的节点 并继续遍历
      deleteChild(returnFiber, currentFiber);
      currentFiber = currentFiber.sibling;
    }
  }
  // 创建fiber
  const fiber = createFiberFormElemnt(element);
  fiber.return = returnFiber;
  return fiber;
}