在 React 源码中,scheduleUpdateOnFiber 是所有任务的唯一入口方法。我们前面分析 useState 的实现原理章节中,我们可以清晰的知道,当我们调用 dispatchSetState 时,最终会调用该入口方法。
scheduleUpdateOnFiber 主要用于触发一个 Fiber 节点上的调度更新任务,该函数里主要有两个核心逻辑。
markRootUpdated 的逻辑如下,简单了解一下即可。
ensureRootIsScheduled 的主要目的要确保 root 根节点被调度。在该逻辑中,会根据 root.pendingLanes 信息计算出本次更新的 Lanes: nextLanes。
然后根据 nextLanes 计算出本批次集合中优先级最高的 Lane,作为本地任务的优先级。
后续的逻辑就是取出当前已存在的调度优先级,与 newCallbackPriority 进行对比,根据对比结果来执行不同的更新方法。当该值等于 SyncLane 时,表示为同步更新。
同步优先级例如点击事件。
然后会判断是否支持微任务更新,如果不支持最后会执行 scheduleCallback。
scheduleSyncCallback 的逻辑,也就是同步任务的调度非常简单,就是将执行同步任务的回调添加到一个同步队列 syncQueue 中。
这里的 callback 是之前传入的 performSyncWorkOnRoot,这是用来执行同步更新任务的方法。他的逻辑主要包括:
- 调用 renderRootSync,该方法会执行 workLoopSync,最后生成 Fiber true。
- 将创建完成的 Fiber tree 挂载到 root 节点上。
- 最后调用 commitRoot,进入 commit 阶段修改真实 DOM。
workLoopSync 的逻辑也非常简单,如下:
在 performUnitOfWork 中,会调用 beginWork 方法开始创建 Fiber 节点。
总结
同步更新的过程比较简单,从 scheduleUpdateOnFiber 到 beginWork 这中间的流程里,大多数逻辑都在进行各种不同情况的判断,因此源码看上去比较吃力,实际逻辑并不是很重要,简单了解即可,重要的是 beginWork 创建 Fiber 节点的方法,这跟我们之前文章里提到过的优化策略是一致的。