Skip to content

Commit fce38e5

Browse files
committed
四: render 和 commit 分离
1 parent 5b5c5fa commit fce38e5

File tree

3 files changed

+25
-9
lines changed

3 files changed

+25
-9
lines changed

src/mini-react/commit.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// 从根节点开始 commit
2+
export function commitRoot(rootFiber) {
3+
commitWork(rootFiber.child);
4+
}
5+
6+
// 递归执行 commit,此过程不中断
7+
function commitWork(fiber) {
8+
if (!fiber) {
9+
return;
10+
}
11+
// 深度优先遍历,先遍历 child,后遍历 sibling
12+
commitWork(fiber.child);
13+
let parentDom = fiber.return.stateNode;
14+
parentDom.appendChild(fiber.stateNode);
15+
commitWork(fiber.sibling);
16+
}

src/mini-react/fiber.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { renderDom } from './react-dom';
2+
import { commitRoot } from './commit';
23

34
let nextUnitOfWork = null;
45
let rootFiber = null;
@@ -21,15 +22,6 @@ function performUnitOfWork(workInProgress) {
2122
// 若当前 fiber 没有 stateNode,则根据 fiber 挂载的 element 的属性创建
2223
workInProgress.stateNode = renderDom(workInProgress.element);
2324
}
24-
if (workInProgress.return && workInProgress.stateNode) {
25-
// 如果 fiber 有父 fiber且有 dom
26-
// 向上寻找能挂载 dom 的节点进行 dom 挂载
27-
let parentFiber = workInProgress.return;
28-
while (!parentFiber.stateNode) {
29-
parentFiber = parentFiber.return;
30-
}
31-
parentFiber.stateNode.appendChild(workInProgress.stateNode);
32-
}
3325

3426
let children = workInProgress.element?.props?.children;
3527

@@ -111,6 +103,11 @@ function workLoop(deadline) {
111103
performUnitOfWork(nextUnitOfWork);
112104
shouldYield = deadline.timeRemaining() < 1;
113105
}
106+
if (!nextUnitOfWork && rootFiber) {
107+
// 表示进入 commit 阶段
108+
commitRoot(rootFiber);
109+
rootFiber = null;
110+
}
114111
requestIdleCallback(workLoop);
115112
}
116113

src/mini-react/react-dom.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ export function renderDom(element) {
3333
if (typeof type === 'string') {
3434
// 常规 dom 节点的渲染
3535
dom = document.createElement(type);
36+
} else if (typeof type === 'function') {
37+
// React 组件的渲染
38+
dom = document.createDocumentFragment();
3639
} else {
3740
// 其他情况暂不考虑
3841
return null;

0 commit comments

Comments
 (0)