Provider 和 Store
仅仅使用atom
和useAtom
基本上就已经可以完成 Jotai 在一般项目中的使用了,但是在 Jotai 控制所有 atom 逻辑的背后,还有两个非常重要的基础设施存在,虽然这两个功能可能在项目中使用的几率偏小,但这并不等于它们就不重要。
Store
在 Jotai 的实际运行过程中,所有的 atom 并不是散在项目中的,它们都被存储在一个默认的 Store 中。这个默认的 Store 无需我们显式创建,它会由 Jotai 自动创建并放置进入组件树。
Store 中保存的都是各个 atom 的实例,所以比较有经验的读者看到这里,就应该可以想到,Store 是可以用来在组件树里创建和隔离 atom 实例的。事实上 Store 的常见用法也的确如此。
与 atom 一样,Store 也是一个需要定义在组件外部的内容。创建一个新的 Store 实例可以直接使用createStore
函数,这个函数不需要参数,它的功能就是完成一个 Store 实例的创建。
一个 Store 所具备的基本功能是获取指定 atom 的值,更新指定 atom 的值和订阅 atom 的变化。这三个功能分别由 Store 实例的get
、set
和sub
三个方法提供。
这三个方法大部分情况下不需要我们手动去调用,下文介绍的Provider会代替我们完成Store的控制。不过在组件之外获取和更新atom的值还是要使用到Store提供的功能的,比如在React Router的load
和action
方法中获取和更新atom的值。
对于 Jotai 提供的默认 Store,可以使用 Jotai 提供的函数getDefaultStore()
来获取。这可以在不使用 Provider 的时候在项目中组件外部更新 atom 使用。
Provider
Provider 在上面一节中就已经提到了,它是 Jotai 提供的一个组件,它的主要功能就是向组件树中提供 atom 实例。Provider 在组件树中可以多次出现,嵌套使用还可以形成类似于 React 中Context
的隔离上下文的功能。
如果在项目中不使用任何 Provider,那么这种模式在 Jotai 中被称为Provider-less
模式,在这个模式下项目中所有的 atom 都将被保存在默认 Store 中,并且每一个 atom 有且仅有一个实例。
Provider 组件常用的属性是store
,用来指定其下组件树中所访问的 atom 实例所保存的位置。一个 Provider 常见的使用形式是这样的:
const customStore = createStore();
const Root = () => {
return (
<Provider store={customStore}>
<App />
</Provider>
);
};
在一个 Provider 下的组件树中要获取 Provider 提供的 Store,可以使用useStore
Hook。