1、存在问题
这里还存在一个问题,就是每次处理一个元素,都要向DOM添加一个新的节点,在完成整个树的渲染之前,由于做了可中断操作,那将看到一个不完整的UI,这样显然是不行的。
2、处理步骤
1.删除子节点添加到父节点的逻辑;
function performUnitOfWork(fiber) {// 这段逻辑删了if (fiber.parent) {fiber.parent.dom.appendChild(fiber.dom)}}
2.添加fiber根节点wipRoot,并设置为下一个工作单元;
let wipRoot = nullexport function render(element, container) {// 将根节点设置为第一个工作单元wipRoot = {dom: container,props: {children: [element],},}nextUnitOfWork = wipRoot}
3.当完成了所有任务,也就是说没有下一个工作单元了,这时需要把整个fiber渲染为DOM;
// 提交任务,将fiber tree 渲染为真实 DOMfunction commitRoot(){}function workLoop(deadline) {// 省略// 没有下一个工作单元,提交当前fiber树if (!nextUnitOfWork && wipRoot) {commitRoot()}// 省略}
4.在 commitRoot 函数中执行提交工作,递归将所有节点附加到 dom 中;
/*** 处理提交的fiber树* @param {*} fiber* @returns*/function commitWork(fiber){if (!fiber) {return}const domParent = fiber.parent.dom// 将自己点添加到父节点下domParent.appendChild(fiber.dom)// 渲染子节点commitWork(fiber.child)// 渲染兄弟节点commitWork(fiber.sibling)}/*** 提交任务,将fiber tree 渲染为真实 DOM*/function commitRoot(){commitWork(wipRoot.child)wipRoot = null}
3、运行结果
运行结果没有问题
4、本节代码
代码地址:https://github.com/linhexs/mini-react/tree/5.RenderAndCommit
