跳至主要内容

Recoil 0.0.11

·6 分钟阅读

今天我们发布了 Recoil 0.0.11。它包含错误修复、新功能、更佳性能以及与并发模式的实验性兼容性。感谢所有为此次发布做出贡献的人!

实验性并发模式支持

Recoil 现在支持 并发模式,当与 React 的 experimental 版本一起使用时。请尝试一下并报告任何问题!

并发模式,它可以提供更流畅、更一致的用户体验,是 React 的未来。但直到现在,它一直与任何类型的外部状态不兼容。这是因为,在并发模式下,渲染可以分散在一段时间内:React 可以暂停组件的渲染,然后在稍后从它已经构建的部分组件树开始继续渲染。

React pauses while rendering a tree of components. Some components are rendered before the pause while others are rendered after the pause.

这给外部状态带来了一个问题。由于 React 现在放弃了控制流,因此渲染开始和完成之间可能发生任何事情。如果外部状态在此期间发生变化,会导致 UI 不一致,因为较早渲染的组件将观察到旧的状态,而较晚渲染的组件将观察到新的状态。

If components depend on some external state, and that state changes while rendering is paused, then components rendered before the pause will observe the old state, while components rendered after the pause will observe the new state.

这种不一致会导致问题,甚至会使应用程序崩溃。

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!更多版本即将发布。