JotaiJotai

状態
Primitive and flexible state management for React

迁移到 Jotai v2 API

RFC: https://github.com/pmndrs/jotai/discussions/1514

Jotai v1 于 2022 年 6 月发布,收到了各种反馈。 React 还提出了对 promise 的支持。 Jotai v2 将有一个新的 API。

不幸的是,随着新功能的出现,有一些重大变化。

什么是新功能

Vanilla 库

Jotai 分别带有 vanilla(非 React)函数和 React 函数。

Store API

Jotai 暴露了存储接口,以便您可以直接操作原子值。

import { createStore } from "jotai/vanilla";
const store = createStore();
store.set(fooAtom, "foo");

您还可以创建自己的 React 上下文来传递 store。

更灵活的原子write函数

write 函数可以接受多个参数,并返回一个值。

atom(
(get) => get(...),
(get, set, arg1, arg2, ...) => {
...
return someValue
}
)

什么东西坏了

Import 声明

新的 API 从不同的入口点提供:

  • jotai/vanilla
  • jotai/vanilla/utils
  • jotai/react
  • jotai/react/devtools
  • jotai/react/utils
import { atom } from "jotai/vanilla";
import { useAtom } from "jotai/react";

这些新的入口点作为预发布版本添加到 v1.11.0 中,将在 v2.0.0 发布后继续工作。

在 v2.0.0 中,它们是默认值,旧入口点仅引用新入口点。

// v2
import { atom } from "jotai"; // 与'jotai/vanilla'相同
import { useAtom } from "jotai"; // 与 'jotai/react' 相同

异步原子不再特殊

异步原子只是具有 promise 值的普通原子。 原子 getter 函数不解析 promise。 另一方面,useAtom hook 继续解析 promise。

可写原子类型已更改(仅限 TypeScript)

// 旧
WritableAtom<Value, Arg, Result extends void | Promise<void>>
// 新
WritableAtom<Value, Args extends unknown[], Result>

一般来说,我们应该避免直接使用 WritableAtom 类型。

一些功能被删除

  • Provider 的 initialValues 属性被移除,因为 store 更灵活。
  • Provider 的范围属性被删除,因为您可以创建自己的上下文。
  • abortableAtom 工具被删除,因为默认包含该功能
  • waitForAll 工具被删除,因为 Promise.all 可以正常工作

迁移指南

异步原子

get函数用于异步原子的读取函数不解析 promise,所以你必须放 await

简而言之,更改如下所示。 (如果您是 TypeScript 用户,类型会告诉您在哪里更改。)

以前的 API

const asyncAtom = atom(async () => "hello");
const derivedAtom = atom((get) => get(asyncAtom).toUppercase());

新 API

const asyncAtom = atom(async () => "hello");
const derivedAtom = atom(async (get) => (await get(asyncAtom)).toUppercase());

Provider 的 initialValues 属性

Previous API

const countAtom = atom(0)
<Provider initialValues={[[countAtom, 1]]}>
...
</Provider>

新 API

const countAtom = atom(0)
const store = createStore()
store.set(countAtom, 1)
<Provider store={store}>
...
</Provider>

Provider 的 scope 属性

旧 API

const myScope = Symbol()
// 父组件
<Provider scope={myScope}>
...
</Provider>
// 子组件
useAtom(..., myScope)

新 API

const MyContext = createContext()
const store = createStore()
// 父组件
<MyContext.Provider value={store}>
...
</MyContext.Provider>
// 子组件
const store = useContext(MyContext)
useAtom(..., { store })

abortableAtom util

您不再需要以前的 abortableAtom utils,因为现在普通的 atom 支持它。

旧 API

const asyncAtom = abortableAtom(async (get, { signal }) => {
...
}

新 API

const asyncAtom = atom(async (get, { signal }) => {
...
}

waitForAll util

您不再需要以前的 waitForAll 工具,因为我们可以使用原生的 Promise API。

旧 API

const allAtom = waitForAll([fooAtom, barAtom]);

新 API

const allAtom = atom((get) => Promise.all([get(fooAtom), get(barAtom)]));

一些其它改变

  • atomWithStorage util 的 delayInit 作为默认值被删除。
  • useHydrateAtoms 只能接受可写原子。