Jotai 项目中 React 19 与 atomWithObservable 的 Suspense 问题解析
问题背景
在 React 状态管理库 Jotai 的最新使用中,开发者发现当升级到 React 19 后,useAtomValue 与 atomWithObservable 的组合使用会出现一个意外的行为:每当 observable 产生新值时,组件会重新触发 Suspense 状态。这显然不是预期的行为,因为 Suspense 应该只在初始加载时触发,而不应在数据更新时重复触发。
技术细节分析
Jotai 的核心概念
Jotai 是一个基于原子(atom)概念的 React 状态管理库。atomWithObservable 是一个特殊的原子创建函数,它允许将 RxJS 或其他兼容的 observable 转换为 Jotai 原子。useAtomValue 则是用于在 React 组件中订阅原子值的 hook。
React 19 的变化
React 19 引入了一些内部机制的变化,特别是在并发渲染和 Suspense 处理方面。这些变化影响了 Jotai 中 observable 原子的行为模式。具体来说,React 19 对异步值的处理更加严格,导致 observable 发出的每个新值都被视为可能需要重新 Suspense 的场景。
问题表现
当使用以下代码模式时:
const observableAtom = atomWithObservable(() => someObservable);
const value = useAtomValue(observableAtom);
在 React 19 环境下,每当 observable 发出新值时,组件会重新进入 Suspense 状态,导致不必要的加载状态闪烁和性能开销。
临时解决方案
目前发现的有效临时解决方案是给 useAtomValue 添加一个 delay: 0 的配置:
const value = useAtomValue(observableAtom, { delay: 0 });
这个配置通过将值的更新推迟到下一个 macrotask(通过 setTimeout(fn, 0) 实现),绕过了 React 19 的立即 Suspense 行为。
技术原理探究
为什么 delay: 0 有效
设置 delay: 0 实际上是将状态更新从同步改为异步。React 19 的并发渲染器对同步更新和异步更新有不同的处理策略。对于异步更新,React 会采用更宽松的 Suspense 策略,不会为每个新值触发 Suspense。
更深层的机制
这可能与 React 19 对"过渡"(transition)概念的强化有关。React 19 可能将 observable 的每次更新都视为潜在的"关键"更新,从而触发 Suspense。而通过 delay: 0 将其转为异步更新后,React 会将其视为"非关键"更新,从而避免不必要的 Suspense。
长期解决方案展望
虽然 delay: 0 是一个有效的临时解决方案,但长期来看,Jotai 可能需要针对 React 19 进行专门的适配:
- 修改
atomWithObservable的内部实现,使其与 React 19 的并发特性更好地兼容 - 提供专门的 React 19 适配层,自动处理这类边界情况
- 与 React 团队协作,明确 observable 集成的最佳实践
最佳实践建议
对于正在使用或计划使用 Jotai 与 React 19 的开发者:
- 如果遇到 Suspense 相关问题,首先尝试
delay: 0解决方案 - 密切关注 Jotai 的更新日志,特别是关于 React 19 兼容性的说明
- 考虑在 observable 原子外添加一层缓存或防抖,减少不必要的更新
- 对于关键路径,进行充分的测试以确保更新行为符合预期
总结
React 19 的架构变化为状态管理库带来了新的挑战和机遇。Jotai 作为基于原子的轻量级状态管理方案,正在积极适应这些变化。当前 useAtomValue 与 atomWithObservable 的 Suspense 问题虽然可以通过简单的方式解决,但也提醒我们在升级 React 版本时需要全面测试状态管理相关的行为。随着 React 19 的逐步普及,相信 Jotai 团队会提供更加完善的解决方案。
ERNIE-4.5-VL-28B-A3B-ThinkingERNIE-4.5-VL-28B-A3B-Thinking 是 ERNIE-4.5-VL-28B-A3B 架构的重大升级,通过中期大规模视觉-语言推理数据训练,显著提升了模型的表征能力和模态对齐,实现了多模态推理能力的突破性飞跃Python00
Kimi-K2-ThinkingKimi K2 Thinking 是最新、性能最强的开源思维模型。从 Kimi K2 开始,我们将其打造为能够逐步推理并动态调用工具的思维智能体。通过显著提升多步推理深度,并在 200–300 次连续调用中保持稳定的工具使用能力,它在 Humanity's Last Exam (HLE)、BrowseComp 等基准测试中树立了新的技术标杆。同时,K2 Thinking 是原生 INT4 量化模型,具备 256k 上下文窗口,实现了推理延迟和 GPU 内存占用的无损降低。Python00
MiniMax-M2MiniMax-M2是MiniMaxAI开源的高效MoE模型,2300亿总参数中仅激活100亿,却在编码和智能体任务上表现卓越。它支持多文件编辑、终端操作和复杂工具链调用Python00
HunyuanVideo-1.5暂无简介00
MiniCPM-V-4_5MiniCPM-V 4.5 是 MiniCPM-V 系列中最新且功能最强的模型。该模型基于 Qwen3-8B 和 SigLIP2-400M 构建,总参数量为 80 亿。与之前的 MiniCPM-V 和 MiniCPM-o 模型相比,它在性能上有显著提升,并引入了新的实用功能Python00
Spark-Formalizer-X1-7BSpark-Formalizer 是由科大讯飞团队开发的专用大型语言模型,专注于数学自动形式化任务。该模型擅长将自然语言数学问题转化为精确的 Lean4 形式化语句,在形式化语句生成方面达到了业界领先水平。Python00
GOT-OCR-2.0-hf阶跃星辰StepFun推出的GOT-OCR-2.0-hf是一款强大的多语言OCR开源模型,支持从普通文档到复杂场景的文字识别。它能精准处理表格、图表、数学公式、几何图形甚至乐谱等特殊内容,输出结果可通过第三方工具渲染成多种格式。模型支持1024×1024高分辨率输入,具备多页批量处理、动态分块识别和交互式区域选择等创新功能,用户可通过坐标或颜色指定识别区域。基于Apache 2.0协议开源,提供Hugging Face演示和完整代码,适用于学术研究到工业应用的广泛场景,为OCR领域带来突破性解决方案。00