概览
由react核心成员里克·汉隆发表的并行模式可能造成的外部状态库的影响以及解决方案分级,阅读这篇文章你可以了解到:
- 可能对哪些状态库造成影响
- 影响的现象是什么
- 状态库适配并发模式的几种等级
- 并发模式对状态库造成影响的案例
前置知识
:React 18 并发模式
可能对哪些状态库造成影响
可以看到第一处划线的部分,作者说不使用外部可变数据,仅使用react原生的props、state、context的不会受到影响,因为react原生处理了并发。
第二处作者说产生的影响叫撕裂(tearing),在渲染过程中外部数据发生了改变,导致渲染结果不一致的现象。具体可参见地址:github.com/reactwg/rea…
状态库适配并发模式的几种等级
我们可以清晰的看到作者划分了三个等级,分别是:
- 可以工作:使用useSubscription(目前该api已经不维护,所以不用考虑这种情况)进行外部数据源的订阅,原理是:当数据源改变渲染完成后同步发起一次渲染以修复撕裂(tearing)的状态。
- 工作正常:使用useSyncExternalStore订阅外部源,原理是当数据源改变时立即触发渲染,与1不同的是它会在展示之前触发一次重渲染。最坏的影响是本次渲染时间过长,但不会出现撕裂状态。
- 运行快速:使用react本身提供的钩子进行状态管理,或者使用不可变数据(但是这个策略目前还在研究)
并发模式对状态库造成影响的案例
react团队核心丹·阿布拉莫夫提供了一个tearing的示例(注意第一次触发展示的数据的不同):
可以看出dan总将:
- 外部数据通过setState设置为内部状态
- 每隔50ms改变外部数据,并当数据变动触发订阅setState回调
- 利用循环延迟执行
造成一次渲染时间超过数据变更时间,导致组件订阅的外部数据不同步。
基于上述的改进法则我使用useExternalStore适配了这种割裂情况,详情见示例:
总结
并发模式可能影响不使用react原生api编写的外部状态管理库,影响的现象为割裂。外部库适配并发模式分为三个等级:可以用(有割裂,但能修复)、工作正常(渲染时间更长)、运行快速。并且通过Dan的一个demo演示了割裂现象及修复。