From 538421d67d76e2e48ee5fcadbb0369a19fe963cc Mon Sep 17 00:00:00 2001 From: zh-lx <18366276315@163.com> Date: Mon, 8 Nov 2021 23:21:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=94:=203.diff=20=E5=B9=B6=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20flag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mini-react/reconciler.js | 60 ++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/src/mini-react/reconciler.js b/src/mini-react/reconciler.js index bf96d7c..073b67d 100644 --- a/src/mini-react/reconciler.js +++ b/src/mini-react/reconciler.js @@ -1,24 +1,64 @@ export function reconcileChildren(workInProgress, elements) { let index = 0; // 当前遍历的子元素在父节点下的下标 let prevSibling = null; // 记录上一个兄弟节点 + let oldFiber = workInProgress?.alternate?.child; // 对应的旧 fiber - while (index < elements.length) { - // 遍历子元素 + while (index < elements.length || oldFiber) { + // 遍历 elements 和 oldFiber const element = elements[index]; // 创建新的 fiber - const newFiber = { - element, - return: workInProgress, - stateNode: null, - }; + let newFiber = null; + const isSameType = + element?.type && + oldFiber?.element?.type && + element.type === oldFiber.element.type; + + // 添加 flag 副作用 + if (isSameType) { + // type相同,表示更新 + newFiber = { + element: { + ...element, + props: element.props, + }, + stateNode: oldFiber.stateNode, + return: workInProgress, + alternate: oldFiber, + flag: 'Update', + }; + } else { + // type 不同,表示添加或者删除 + if (element || element === 0) { + // element 存在,表示添加 + newFiber = { + element, + stateNode: null, + return: workInProgress, + alternate: null, + flag: 'Placement', + index, + }; + } + if (oldFiber) { + // oldFiber存在,删除 oldFiber + oldFiber.flag = 'Deletion'; + } + } + + if (oldFiber) { + // oldFiber 存在,则继续遍历其 sibling + oldFiber = oldFiber.sibling; + } + if (index === 0) { // 如果下标为 0,则将当前fiber设置为父 fiber 的 child workInProgress.child = newFiber; - } else { - // 否则通过 sibling 作为兄弟 fiber 连接 + prevSibling = newFiber; + } else if (newFiber) { + // newFiber 和 prevSibling 存在,通过 sibling 作为兄弟 fiber 连接 prevSibling.sibling = newFiber; + prevSibling = newFiber; } - prevSibling = newFiber; index++; } }