今天我们发布了 Recoil 0.0.11。它包含错误修复、新功能、更佳性能以及与并发模式的实验性兼容性。感谢所有为此次发布做出贡献的人!
实验性并发模式支持
Recoil 现在支持 并发模式,当与 React 的 experimental
版本一起使用时。请尝试一下并报告任何问题!
并发模式,它可以提供更流畅、更一致的用户体验,是 React 的未来。但直到现在,它一直与任何类型的外部状态不兼容。这是因为,在并发模式下,渲染可以分散在一段时间内:React 可以暂停组件的渲染,然后在稍后从它已经构建的部分组件树开始继续渲染。
这给外部状态带来了一个问题。由于 React 现在放弃了控制流,因此渲染开始和完成之间可能发生任何事情。如果外部状态在此期间发生变化,会导致 UI 不一致,因为较早渲染的组件将观察到旧的状态,而较晚渲染的组件将观察到新的状态。
这种不一致会导致问题,甚至会使应用程序崩溃。
Recoil 现在利用 React 中的实验性 API 来处理这种情况,当 Recoil 状态在渲染期间发生变化时,会使用新的树重新启动。这些 API 也使 Recoil 更高效,并消除了在组件首次挂载时重新渲染组件的需要。
避免在生产环境中使用 React 实验性版本。无论你使用的是哪个版本的 React 或状态管理库,始终将副作用放在 useEffect()
钩子中,而不是在渲染期间,以避免错误! (@davidmccabe, @bvaughn)
性能
一些变化提高了 Recoil 的性能。以前,Recoil 有时必须在某些情况下重新渲染组件:从依赖关系未知的选择器读取时,以及从已从外部存储初始化的原子读取时。现在,Recoil 不再需要执行第二次渲染来响应原子或选择器的读取。 (@davidmccabe)
其次,当与 React 的 experimental
版本一起使用时,Recoil 不再需要在组件最初挂载时执行第二次渲染。Recoil 也不再需要做任何工作来查找原子或选择器值,当它因除原子或选择器更改以外的原因重新渲染时。 (@davidmccabe, @bvaughn).
诸如 useRecoilValue()
和 useRecoilState()
之类的基本钩子已得到优化,现在速度提高了约 8 倍×快。它们现在通常比 useState()
快 2 倍×执行。这提高了在许多组件中使用大量原子的应用程序的性能。 (@davidmccabe)
Recoil 会递归地冻结原子和选择器的内容。这可以防止错误,但对于大型对象来说可能会很慢。现在,它只在开发构建中发生。 (#361— @drarmstr)
如果将原子设置为其已设置的值,或者在它已经重置时重置它,Recoil 现在将避免重新渲染组件或重新计算选择器 (#399, #386— @drarmstr).
最后,此版本还修复了在先前版本中引入的内存泄漏。如果你在频繁更新原子的应用程序中遇到性能下降,这很可能是原因。 (#471— @davidmccabe)
类型和打包
除了 TypeScript 之外,现在还将 Flow 类型 与包一起导出。Flow 是 Facebook 使用的类型系统,Recoil 实际上也是用它编写的。 (#338, #468, #541— @Brianzchen, @Komalov, @mondaychen)
TypeScript 类型也得到了改进 (#492, #545, #548, #568, #575— @csantos42, @SergeyVolynkin, @drarmstr, @hachibeeDI).
除了 NPM 包之外,我们现在还提供 通过 CDN 的 Common JS 和 UMD 模块 (#413— @mondaychen, @pocket7878).
支持多个 React 根目录
你现在可以 在多个 React 根目录之间共享状态。例如,如果你的应用程序同时使用 React DOM 和另一个渲染器(如 ThreeJS),你现在可以在它们之间共享 Recoil 状态。与始终使用多个 React 根目录一样,它们可能暂时不同步。 (#298, #516— @drarmstr, @inlet)
开发者工具 API
此版本包含 实验性 API,旨在用于开发者工具。我们正在内部创建一套开发者工具,并且还有一些开源项目正在进行中。我们发布这些 API 是为了帮助验证它们的設計。 (@drarmstr)
其他新的 API
你现在可以使用 Promise 作为原子的默认值。当读取它时,它将表现得像一个异步选择器。 (@drarmstr)
错误修复
此更新包含许多与测试基础设施以及开源环境和 Facebook 内部环境之间的差异相关的修复。 (#368, #360, #362, #363, #392, #431, #402, #538, #539, #549, #561, #576— @aaronabramov, @Komalov, @drarmstr, @jacques-blom, @mondaychen, @dsainati1, @csantos42, @behnammodi, @habond, @benhalverson).
它还修复了使用多个 <RecoilRoot>
或在快照中预加载选择器时的错误 (#534— @davemccabe).
重大变更
此更新可能会破坏某些不使用 react-test-utils
中的 act()
函数 来执行影响 React 组件的操作的测试。这些测试有时仍然可以正常工作,因为 Recoil 的额外渲染。使用 act()
来修复任何此类测试。
如果提供给 Recoil 的状态更新器函数在其自身的执行过程中导致另一个原子更新,Recoil 现在将抛出异常。状态更新器函数应该纯粹的,所以这始终违反 API 契约。但它在之前的某些情况下碰巧可以正常工作,现在不行了。可以更改执行此操作的代码,以便使用 useRecoilCallback()
执行效果。
未来工作
在未来的版本中,Recoil 将自动释放不再使用的原子和选择器使用的内存,并且在使用大量原子时将表现更好。 (@davidmccabe)
我们还在开发用于将 Recoil 原子与外部数据源(如 URL、本地存储或服务器)同步的 API。 (@drarmstr)
开发者工具正在开发中。 (@maxijb, @habond, @drarmstr)
感谢您阅读至此并使用 Recoil!更多版本即将发布。