最近帖子
标签筛选 #react · 共 1 条
#优质博文#前端#工程化#React Two React Design Choices Developers Don’t Like—But Can’t Avoid:SolidJS 作者 Ryan Carniato 揭示 React 两个"令人讨厌"的设计选择(延迟状态提交、Effect 依赖数组)背后的深层约束,这些是所有 UI 模型在异步场景下必然遇到的 invariant。 AI 摘要:SolidJS 作者 Ryan Carniato 在开发 Solid 2.0 过程中发现,React 的两个被开发者诟病的设计选择:延迟状态提交和 Effect 依赖数组,并非任意决定,而是所有响应式系统在面对异步时必然遭遇的深层约束。Signal 看似"修复"了这些问题,实则只是暂时隐藏了真相。当异步进入状态图,同步世界的安全感随即崩塌,框架必须承认异步是一等公民,否则将面临一致性和可预测性的双重崩塌。 [以下是方便搜索索引的大纲(AI 生成),请读原文]Ryan Carniato 1. 异步世界的本质 • Web 平台本质上由客户端/服务器之间的网络边界定义,一切都是异步的 • 异步不是混乱,而是时间,需要语言直接表示它 • 返回 null、undefined 或包装器会破坏确定性,继续执行则产生与任何实际时刻都不对应的结果 • 唯一保持一致的方式是停止等待 2. 异步必须与提交隔离 • React 的状态与渲染紧耦合迫使其早期面对这个问题 • Signal 虽保持状态与派生状态同步,但当派生值变为异步时,这种信心会成为负担 • 如果要保持 UI 一致性,必须延迟提交;一旦延迟 UI 提交,数据也必须延迟,否则两者会漂移 • 同步世界的安全感是建立在所有派生值都立即可用的假设上,这个假设一旦涉及异步就会崩溃 3. Effect 依赖必须在计算时已知 • React 在运行任何渲染或副作用前就知道树的全部依赖,这对异步至关重要 • 如果渲染可以在任何时候被中断,副作用就不能绑定到渲染 • Signal 的同步精确更新在纯同步世界看似完美,但一旦异步进入图中,可预测性立即蒸发 • 解决方案:必须将依赖收集与副作用执行分离,副作用只在所有依赖的异步源都 settled 后才运行 4. Signal 解决方案的启示 • 编译器无法修复语义问题,异步是运行时现象,保证必须在运行时执行 • 编译器只能看到作用域内的东西,无法看到整个图 • Svelte 5 迁移到 Runes(Signal)正是因为编译器无法追踪语法上不可见的源 • 这不是模仿 React,而是承认 React 首先遇到的相同基本事实 5. 结论:拥抱不可避免的约束 • 异步强制提交隔离、强制 Effect 拆分、强制一致快照 • 这些不是 React 特有的,它们是任何想在异步存在下保持一致性的系统的 invariant • 采纳这些 invariant 不会抹去 Signal 的优势(细粒度更新、无组件重渲染、深度依赖发现) author Ryan Carniato