派生 store

从一个 store 中派生出另外一个 store 的功能没有在 valtiovaltio/utils 两个包中提供,如果需要这个功能的话,需要安装 derive-valtio 包。

derive-valtio 提供的 derive 函数主要提供了两种功能:

  • 定义一个新的被代理对象,该对象的属性值是根据其他的被代理对象的属性计算得到的。
  • 为当前的被代理对象增加一个派生属性,这个派生属性是根据当前被代理对象或者其他被代理对象的属性计算得到的。

定义一个新的被代理对象

例如现在有一个 store 如下:

const store = proxy({
  count: 1,
});

那么使用 derive 来派生一个新的 store 就可以像下面这个示例中来进行。

import { derive } from "derive-valtio";

const doubledStore = derive({
  doubled: (get) => get(store).count * 2,
});

从上面这个示例中的可以看出来,derive 定义一个派生属性的原理实际上是通过一个函数来完成的,跟 watch 一样,这个函数也是具有一个 get 参数用来获取相关的 store 快照,并声明当前派生 store 对于哪些 store 是依赖的。

Caution

注意,如果派生出来的 store 没有使用到原始 store 中的所有属性,并且原始 store 中未被派生 store 使用的属性发生了变化,那么派生 store 同样也会被重新计算,因为在上例这种使用方式中,派生 store 依赖的是原始 store 本身,而不是原始 store 中的某个或者某些属性。

Question

想想如果派生 store 依赖的是原始 store 中的某个嵌套的代理属性,那么在原始 store 中其他属性发生变化的时候,这个派生 store 还会被重新计算吗?

为当前 store 添加派生属性

为当前 store 添加派生属性,需要使用到 derive 函数的一个比较复杂的用法。例如现在将 doubled 属性追加到 store 里。

derive(
  {
    doubled: (get) => get(store).count * 2,
  },
  {
    proxy: store,
  }
);

在上面的代码中,derive 函数的第二个参数是一个配置对象,其中 proxy 属性指定了派生属性所要附加到的原始 store。

终止派生

在一些情况下可能需要结束当前的派生并重新定义新的派生,那么所需要结束的派生就可以使用 derive-valtio 提供的 underive 函数来结束。这个函数的使用非常简单,直接将所需要结束订阅的派生 store 交给 underive 函数即可。