1 currentRoot 记录当前的 fiber结构
- 在commitRoot 时候,执行完统一提交, 也就是commitWork
- 在清空当前正在处理的wipRoot之前,赋值 currentRoot = wipRoot
let count = 10
function App() {
return (
<button
id="btn"
onClick={() => {
count++;
React.update();
}}
>
{count}
</button>
);
}
<div id="root">
<button id="btn">10</button>
</div>
currentRoot = {
dom: div#root,
props: {
children: [
{
type: f App(),
props: { id: app},
}
]
},
child: {
dom: null,
effectTag: "PLACEMENT",
parent: {dom:div#roo, props: {}, ...},
props: { id: app},
type: f App(),
sibling: null,
child: {
type: 'button',
sibling: null,
dom: buttom#btn
effectTag: "PLACEMENT",
props: {
id: btn,
children: [
{
type: "TEXT_ELEMENT",
props: {
nodeValue: 10
}
}
],
onClick: () => {}
},
parent: {},
child: {
dom: text#10,
effectTag: "PLACEMENT",
parent: {},
props: {nodeValue: 10, children: Array(0)},
sibling: null,
type: "TEXT_ELEMENT"
}
}
}
}
2 此时页面呈现的是 一个 内容为10 的button,当点击按钮 时候,触发click 事件,conut 变为 11,然后执行 React.update 方法
3 React.update 方法
function update() {
wipRoot = {
dom: currentRoot.dom,
props: currentRoot.props,
alternate: currentRoot,
};
nextWorkOfUnit = wipRoot;
- 创建 新的 工作中的根节点 wipRoot,并与 currentRoot 建立关系 ,并赋给当前的工作单元 nextWorkOfUnit = wipRoot
- 工作中的根节点 wipRoot 生命周期是 从render 到 commitRoot,然后 赋值 null
- nextWorkOfUnit 最初是 wipRoot, 随着程序递归是发生变化的,直到为 null,进入 commitRoot 阶段
4. 执行 workLoop, 满足 performUnitOfWork 的执行条件, 处理各个工作单元
- div#root
- 如果没有dom, 创建dom并updateProps:属性只有children,不用处理。
- reconcileChildren:fiber.child = {}
fiber.child = {
type: child.type,
child: null,
sibling: null,
parent: fiber,
props: child.props,
dom: oldFiber.dom,
effectTag: "UPDATE",
alternate: oldFiber,
}
5 执行下一轮 workLoop,
- App() 函数组件
- 只处理reconcileChildren
fiber.child = {
type: child.type,
child: null,
sibling: null,
parent: fiber,
props: child.props,
dom: oldFiber.dom,
effectTag: "UPDATE",
alternate: oldFiber,
}
6 执行下一轮 workLoop
- button#btn
- 如果没有dom, 创建dom并updateProps:children不用处理,id没变不处理,onClick 没变可以不出来
- reconcileChildren:fiber.child = {}
fiber.child = {
type: child.type,
child: null,
sibling: null,
parent: fiber,
props: child.props,
dom: oldFiber.dom,
effectTag: "UPDATE",
alternate: oldFiber,
}
7. 执行下一轮 workLoop
- text 节点
- 如果没有dom, 创建dom并updateProps:children = [] 不用处理,nodeValue 改变了,更新nodeValue
- reconcileChildren,没有children,不执行
8. 执行完毕,或者说,workLoop 里没有符合条件的 performUnitOfWork 了。
9. 进入 commitRoot(fiberRoot.child), 也就是 commitWork(fiber)
- PLACEMENT, 添加dom
- UPDATE,更新属性updateProps
- 递归 commitWork(fiber.child);
- 递归 commitWork(fiber.sibling);
- currentRoot = wipRoot;
- wipRoot = null; 结束更新的生命周期