React Native开发经验集Web前端之路让前端飞

React 源码解析 - commitRoot 更新任务 dom

2019-08-23  本文已影响1人  coolheadedY

commitRoot 三个阶段

commitRoot 准备阶段

核心任务

标记全局变量

标记 fiberRoot 的

markCommittedPriorityLevels 方法主要是找到子树中 NoWork 的节点,对 任务完成后剩余时间 root.nextExpirationTimeToWorkOn 和 root.expirationTime 进行更新,同时更新 root 下子树最早更新和最晚更新的 [ root.earliestPendingTime, root.latestPendingTime ] 区间

检查 finishedWork 是否也有 effect ,如有插入 effect 链表中

finishedWork 就是当前 commit 处理的任务

effectTag 列表 根据 finishedWork 自身是否有 effect 构建成最后的 nextEffect 链表

commitRoot 第一次循环执行

核心任务

在 class 组件中通过 prevProps, prevState 获取状态快照,用于 componentDidUpdate 生命周期
状态快照的获取通过 getSnapshotBeforeUpdate 生命周期 (旧 componentWillUpdate) 执行后的返回值
这个循环中,这个节点即将更新但是还没更新。

getSnapshotBeforeUpdate 生命周期

componentDidUpdate 第三个参数的 snapshot 就是 getSnapshotBeforeUpdate 的返回值

commitBeforeMutationLifecycles

commitRoot 的第一次循环主要是对 nextEffect 链表的任务执行 commitBeforeMutationLifecycles commitBeforeMutationLifecycles 根据 nextEffect.effectTag 是否有 Snapshot 把 nextEffect.alternate fiber 对象和 nextEffect 传入 commitBeforeMutationLifeCycles 中

commitBeforeMutationLifeCycles 中只有在更新任务是 classComponent 时才有工作,
根据 current(nextEffect.alternate) 是否存在判断是否是初次加载,

组件初次加载执行 DidMount 生命周期函数不走 DidUpdate 不需要保存快照对象,最后快照对象保存在 instance.__reactInternalSnapshotBeforeUpdate 上

commitRoot 第二次循环执行

核心任务

重置文本节点
操作 ref
执行 插入、更新、删除的 effect 操作
真正的对 dom 进行操作

commitAllHostEffects

对 nextEffects 链表任务开始第二次循环 commitAllHostEffects 中对不同 effectTag 进行不同操作

commitPlacement 插入节点

commitWork 更新节点

commitDeletion 删除节点

commitRoot 第三次循环执行

核心工作

首次渲染执行componentDidMount
更新渲染执行 componentDidUpdate
执行 setState 的 callback 回调函数
捕获错误

源码流程

commitRoot 收尾工作

结束 commitRoot 还原变量,通知 开发工具,如果生命周期中产生了新的更新会更新 rooFiber 树的子树中的更新最早最晚区间
上一篇 下一篇

猜你喜欢

热点阅读