React 15 时是 Virtual Dom 一个树形结构,16 之后变成了 Fiber Tree 一个链表结构,好处就不赘述了,对比过程可中断,有执行优先级等等特性。
为了方便,暂且还是以树形方式展示结构,每次 render 之后会生成一个新的 Fiber Tree,在 commit 之后直接替换 FiberRootNode 的 alternate 即可更新整个运行时。
diff 过程大概如下,因为是链表结构,所以会通过 child,sibling 等属性关联,最后 return 还会关联到上级节点。
在创建 createWorkInProgress 时,curren.alternate 和 workInProgress.alternate 会有一个互相引用的过程,后面如果有更新会复用 alternate 对象。
整个过程是先生成 Virtual DOM,比如 renderWithHooks 函数返回一些列子节点对象,然后使用 Virtual DOM 去生成 workInProgress tree,其中比较特别的一点是删除的子节点会放到父节点的 deletions 属性中,其它的动作就是遍历 workInProgress tree 时根据相应的被打上的标记执行相应 DOM 操作即可。
最后的 commit 阶段提交所有变更到 DOM 节点上,然后把 FiberRootNode 的 current 指向到新的 workInProgress tree。