JotaiJotai

Jotai
React 原始而灵活的状态管理

TypeScript

版本要求

Jotai 使用 TypeScript 3.8+ 语法。如果你的 TypeScript 版本是 3.7.5 或更低,请升级你的 TypeScript 版本。

Jotai 重度依赖类型推断,并且需要启用 strictNullChecks。请考虑在你的 tsconfig.json 中添加 "strict": true#550 #802 #838

注意事项

原始 atoms 基本上是类型推断的

const numAtom = atom(0) // 原始数字 atom
const strAtom = atom('') // 原始字符串 atom

原始 atoms 可以显式地进行类型化

const numAtom = atom<number>(0)
const numAtom = atom<number | null>(0)
const arrAtom = atom<string[]>([])

派生 atoms 大部分可以推断出它们的类型

一般来说,这是推荐的方法,因为类型化派生 atoms 可能会有些混淆,特别是对于第一次尝试的人。

// 只读派生 atoms
const readOnlyAtom = atom((get) => get(numAtom))
const asyncReadOnlyAtom = atom(async (get) => await get(someAsyncAtom))
// 只写 atoms
const writeOnlyAtom = atom(null, (_get, set, str: string) => set(fooAtom, str))
const multipleArgumentsAtom = atom(
null,
(_get, set, valueOne: number, valueTwo: number) =>
set(fooAtom, Math.max(valueOne, valueTwo))
);
// 读/写 atoms
const readWriteAtom = atom(
(get) => get(strAtom),
(_get, set, num: number) => set(strAtom, String(num))
)
const asyncReadWriteAtom = atom(
async (get) => await get(asyncStrAtom),
(_get, set, num: number) => set(strAtom, String(num))
)

派生 atoms 也可以显式地进行类型化

如果你遇到需要或想要显式类型化你的派生 atoms 的情况,你也可以这样做。

const asyncStrAtom = atom<Promise<string>>(async () => 'foo')
/**
* 对于只写 atoms,你需要提供三个类型参数。
* 第一个类型参数描述了 atom 返回的值。在下面的例子中,这是 `null`。
* 第二个类型参数描述了你将传递给 "write" 函数的参数(复数)。即使你只计划有一个参数,这个类型也必须是数组,如示例中所示。
* 第三个类型参数描述了 "write" 函数的返回值。通常,没有返回值,这就是为什么我们在下面的例子中使用 `void`。
*/
const writeOnlyAtom = atom<null, [string, number], void>(
null,
(_get, set, stringValue, numberValue) => set(fooAtom, stringValue),
)
/**
* 读/写 atoms 也需要同样的三个类型参数。
* 为了完整性,在这个例子中,我们展示了第一个类型参数也可以描述一个异步 atom。
*/
const readWriteAtom = atom<Promise<string>, [number], void>(
async (get) => await get(asyncStrAtom),
(_get, set, num) => set(strAtom, String(num)),
)

useAtom 是基于 atom 类型进行类型化的

const [num, setNum] = useAtom(primitiveNumAtom)
const [num] = useAtom(readOnlyNumAtom)
const [, setNum] = useAtom(writeOnlyNumAtom)

访问 atom 的值类型

import { ExtractAtomValue, useAtomValue } from 'jotai'
import { userAtom } from 'state'
import { useQuery } from '@tanstack/react-query'
export default function WriteReview(hid) {
const user = useAtomValue(userAtom)
const res = useGetReviewQuery(user)
}
function useGetReviewQuery(user: ExtractAtomValue<typeof userAtom>) {
return fetch('/api/user/' + user.id + '/review')
}