diff算法在前端面试中也算是一个高频考题了,那怎么给面试官一个满分解答呢?难道还是简单的说个“深度优先,同层级比较”吗?这太短小精悍了…!
好了,下面开始进入正题
单节点diff就比较简单了,从同层级的老fiber
节点中找出key
值和type
都相等的老节点,如果该老fiber节点存在,则复用他,然后删除剩余的节点,否则重新生成一个新的fiber
节点(这也就意味着以这个节点为根的子树需要重新生成)。
下面我们来看看单节点diff
的核心源码
function reconcileSingleElement(
returnFiber: Fiber, currentFirstChild: Fiber | null, element: ReactElement, lanes: Lanes
): Fiber {
const key = element.key;
let child = currentFirstChild;
// 遍历同层级的老fiber节点
while (child !== null) {
if (child.key === key) {
const elementType = element.type;
// 从老fiber节点中找出key和type都相同的节点,如果找到则将该节点复用,并删除多余的节点,退出循环
if (child.elementType === elementType) {
deleteRemainingChildren(returnFiber, child.sibling);
const existing = useFiber(child, element.props);
existing.ref = coerceRef(returnFiber, child, element);
existing.return = returnFiber;
return existing;
}
deleteRemainingChildren(returnFiber, child);
break;
} else {
// 如果该fiber节点没匹配上,则删除
deleteChild(returnFiber, child);
}
child = child.sibling;
}
// 能走到这里就意味着无法从老fiber中匹配到key和type都相同的节点,无法复用,需要重新生成
const created = createFiberFromElement(element, returnFiber.mode