问题
在看 react 源码(17.0.2版本)中看到这样的一段,当时觉得好奇,就调试了下,发现跟描述的不一致。
出处: react.iamkasong.com/renderer/pr…
测试Demo
Demo:
调试流程
实际调试下,并不是在 commitRootImpl 中去实现同步刷新,而是在 setState 的实现中,去重新调用了 scheduleUpdateOnFiber(图1),并优先级是 IMMEDIATE_PRIORITY_TIMEOUT, 并在 ensureRootIsScheduled 创建一个 performSyncWorkOnRoot 的 syncQueue 同步更新数组(图2)。进一步调试会发现走到(图3),并没有在 commitRootImpl 中执行 flushSyncCallbackQueue 方法。而是返回了,最后是在 unbatchedUpdates 中去执行了 flushSyncCallbackQueue 来调用 syncQueue (其中的 performSyncWorkOnRoot),并触发 renderRootSync(也就是 workLoopSync),进去 performUnitOfWork 调度阶段, 最后再重新回到 commitRoot(由于是新的一轮 update, 产生的 effectList 是对应 state 所改变的 Fiber),再执行完更新 dom 后,渲染出来页面。
图1:
图2:
图3:
图4:
总结
- 在 commit 阶段触发的更新,都会是
performSyncWorkOnRoot并立即更新的优先级,并重新触发commitRoot继续渲染。 - 批量或许同步更新下,都会 flush 新增的同步更新。