From fce38e53a0980deaab6685f9c2073c2e5058d1a8 Mon Sep 17 00:00:00 2001 From: zh-lx <18366276315@163.com> Date: Wed, 10 Nov 2021 20:51:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9B:=20render=20=E5=92=8C=20commit=20?= =?UTF-8?q?=E5=88=86=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mini-react/commit.js | 16 ++++++++++++++++ src/mini-react/fiber.js | 15 ++++++--------- src/mini-react/react-dom.js | 3 +++ 3 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 src/mini-react/commit.js diff --git a/src/mini-react/commit.js b/src/mini-react/commit.js new file mode 100644 index 0000000..14947af --- /dev/null +++ b/src/mini-react/commit.js @@ -0,0 +1,16 @@ +// 从根节点开始 commit +export function commitRoot(rootFiber) { + commitWork(rootFiber.child); +} + +// 递归执行 commit,此过程不中断 +function commitWork(fiber) { + if (!fiber) { + return; + } + // 深度优先遍历,先遍历 child,后遍历 sibling + commitWork(fiber.child); + let parentDom = fiber.return.stateNode; + parentDom.appendChild(fiber.stateNode); + commitWork(fiber.sibling); +} diff --git a/src/mini-react/fiber.js b/src/mini-react/fiber.js index 1be7234..b057b42 100644 --- a/src/mini-react/fiber.js +++ b/src/mini-react/fiber.js @@ -1,4 +1,5 @@ import { renderDom } from './react-dom'; +import { commitRoot } from './commit'; let nextUnitOfWork = null; let rootFiber = null; @@ -21,15 +22,6 @@ function performUnitOfWork(workInProgress) { // 若当前 fiber 没有 stateNode,则根据 fiber 挂载的 element 的属性创建 workInProgress.stateNode = renderDom(workInProgress.element); } - if (workInProgress.return && workInProgress.stateNode) { - // 如果 fiber 有父 fiber且有 dom - // 向上寻找能挂载 dom 的节点进行 dom 挂载 - let parentFiber = workInProgress.return; - while (!parentFiber.stateNode) { - parentFiber = parentFiber.return; - } - parentFiber.stateNode.appendChild(workInProgress.stateNode); - } let children = workInProgress.element?.props?.children; @@ -111,6 +103,11 @@ function workLoop(deadline) { performUnitOfWork(nextUnitOfWork); shouldYield = deadline.timeRemaining() < 1; } + if (!nextUnitOfWork && rootFiber) { + // 表示进入 commit 阶段 + commitRoot(rootFiber); + rootFiber = null; + } requestIdleCallback(workLoop); } diff --git a/src/mini-react/react-dom.js b/src/mini-react/react-dom.js index 54788fa..6611851 100644 --- a/src/mini-react/react-dom.js +++ b/src/mini-react/react-dom.js @@ -33,6 +33,9 @@ export function renderDom(element) { if (typeof type === 'string') { // 常规 dom 节点的渲染 dom = document.createElement(type); + } else if (typeof type === 'function') { + // React 组件的渲染 + dom = document.createDocumentFragment(); } else { // 其他情况暂不考虑 return null;