Recoil 0.3有什么新内容?

389 阅读5分钟

自从Facebook将Recoil作为其React应用的新标准管理库介绍给世界以来,已经有一段时间了。尽管该库仍处于开源项目的实验旗帜下,但Recoil有前途的功能已经证明了它一个又一个版本的价值。

最近,Facebook接连发布了两个新版本,Recoil 0.2Recoil 0.3。最近的更新引入了一堆错误修复和对整体开发体验的改进。在本指南中,我们将强调一些最重要的新功能。

如果想了解Recoil是如何工作的,请查看我们的Recoil介绍创建CRUD应用程序的指南

Recoil的Snapshot

如果你以前使用过Recoil,你会熟悉原子的概念。原子基本上是Recoil中的一块状态。它由一个atom() 函数表示,该函数返回一个RecoilState 对象,你可以向其写入数据。

因为我们主要使用React Hooks来处理所有事情,Recoil使你能够通过几个Hooks来处理原子,包括 [useRecoilState()](https://recoiljs.org/docs/api-reference/core/useRecoilState).

A Snapshot对象,顾名思义,是这些原子内状态的不可改变的快照。作为一个程序员,你不可能在你的日常生活中使用快照,因为状态在不断变化。然而,它对诸如状态同步、开发工具功能等方面非常有用。

在Recoil中,基本上有三种主要的方式来获取特定状态的快照。

  • 通过useRecoilCallback 钩子,它允许异步访问到一个特定的状态。Snapshot
  • 通过useRecoilSnapshot 钩子,它允许同步访问一个对象。Snapshot
  • 通过useRecoilTransactionObserver_UNSTABLE 钩子,它允许在原子发生任何状态变化时订阅Snapshots。

Recoil 0.3为快照引入了一个轻微的突破性变化。现在,一个Snapshot 对象可能只活到回调或渲染过程结束。如果你目前的代码使用快照的时间超过这个时间,你会看到在开发者模式下,一些警告信息出现在你的控制台。然而,该团队正在开发一个新的API,名为retain() ,以使其使用的时间更长。在即将发布的版本中注意这个功能。

RecoilRoot'soverride

RecoilRoot必须永远是任何使用回收钩子的组件的祖先。它通常被添加到React应用的根组件中。然而,这取决于你,因为你的应用程序也可以共享多个RecoilRoot,代表原子状态的独立存储。

由于这种特殊性,Recoil保证每个原子对于它所属的每个根总是有自己的值。比如说。

const container = renderElements(
  <RecoilRoot>
    <ReadsAtom atom={myAtom} />
    <RecoilRoot>
      <ReadsAtom atom={myAtom} />
    </RecoilRoot>
  </RecoilRoot>
);

在这种情况下,对于嵌套的根的行为仍然是一样的,即内层的根掩盖了外层的根。为了防止这种情况,Recoil 0.3为RecoilRoot 引入了一个新的属性,叫做override

如果一个内部的RecoilRoot ,并将override 属性(默认为true )设置为false ,则不会对其祖先执行任何功能。

const container = renderElements(
  <RecoilRoot>
    <ReadsAtom atom={myAtom} />
    <RecoilRoot override={false}>
      <ReadsAtom atom={myAtom} />
    </RecoilRoot>
  </RecoilRoot>
);

现在,当你,例如,用overridefalse. 卸载一个嵌套的根集时,也会有同样的行为。这个动作不会清理祖先的根原子。

新选择器的getCallback() 功能

一个Recoil选择器是一个无副作用的 "纯函数",它对一组依赖值返回相同的值。Recoil使用它们来确定状态变化何时发生,并通知订阅该特定选择器的组件,以便它能够正确地重新渲染。

选择器可以是只读的,也可以是可写的,这取决于提供的函数。如果你只提供一个get ,选择器会返回一个RecoilValueReadOnly 对象。如果有一个set ,它返回一个RecoilState 对象。

下面是一个简单的例子,说明如何用Recoil使用选择器。

const doubleSelector = selector({
  key: 'DoubleSelector',
  get: ({get}) => get(myAtom) * 2,
});

其逻辑是这样的:如果任何一个选择器的依赖关系得到更新,选择器就会重新评估其get 方法。在我们的例子中,如果myAtom 状态更新,get 方法也会更新,因为我们现在有一个新的双等式的值。很简单,不是吗?

然而,有时候,你可能想使用相同的选择器来返回其中有回调的对象。比方说,你有一个选择器,每当列表中的一个项目的ID更新时,就返回一个组件。选择器检测到这个变化并触发get 方法来重新计算显示项目相关信息的模态。

你可以通过Recoil 0.3中包含的新的getCallback() 函数轻松实现这一目标。

const heySelector = selector({
  key: 'HeySelector',
  get: itemID => ({get, getCallback}) => {
    const onClick = getCallback(({snapshot}) => async () => {
      const item = await snapshot.getPromise(queryForSomethingById(itemID));
      showModal(item);
    });


    return {
      title: `Hey, I'm a component!`,
      onClick,
    };
  },
});

它与我们的useRecoilCallback() 非常相似。然而,getCallback() 函数更适用于你需要稍后访问状态的用例,例如当当前组件上下文之外的一些逻辑需要该对象执行特定操作时。

使用HAMT改善性能

Recoil 0.2引入了一个增强功能,大大改善了原子值克隆的速度。

今天,recoil使用内置的map数据结构来复制和设置原子值的映射,当一个写入发生时。这一变化引入了使用哈希数组映射的Trie(HAMT)实现,它处理关联数组,以结合哈希表和数组映射的Trie(搜索树)的能力。

这一变化使这种写入操作的速度提高了325倍,执行的条目数最多为1000个。有一万个条目的执行速度惊人地增加了3000倍。

你可以在GitHub上看一下新的实现。

结论

Recoil 0.2和0.3版本主要引入了基本和非突破性的变化。其中包括对原子族的时间和内存消耗的可扩展性的改进,在各种使用情况下更友好的错误抛出,对Safari的更好支持,以及更多。

下一个主要版本发布时,你可能会期待一个更大的实质性变化清单,而且Recoil项目会从实验状态迁移到正式状态。

The postWhat's new in Recoil 0.3?appeared first onLogRocket Blog.