核心
基础 APIs
atom
atom
功能是创建一个原子配置。
我们称它为“原子配置”,因为它只是一个定义,还没有任何值。
如果上下文清楚,我们也可以将其称为“原子”。
原子配置是一个不可变的对象。 原子配置对象没有值。 原子值存在于 store 中。
要创建原始原子 (config),您只需提供一个初始值即可。
import { atom } from "jotai";const priceAtom = atom(10);const messageAtom = atom("hello");const productAtom = atom({ id: 12, name: "good stuff" });
您还可以创建派生原子。 我们有三种模式:
- 只读 atom
- 只写 atom
- 读写 atom
为了创建派生原子,我们传递了一个读取函数和一个可选的写入函数。
const readOnlyAtom = atom((get) => get(priceAtom) * 2);const writeOnlyAtom = atom(null, // 为第一个参数传递 `null` 是一种惯例(get, set, update) => {// `update` 是我们收到的用于更新此原子的任何单个值set(priceAtom, get(priceAtom) - update.discount);});const readWriteAtom = atom((get) => get(priceAtom) * 2,(get, set, newPrice) => {set(priceAtom, newPrice / 2);// 您可以同时设置任意数量的原子});
read 函数中的 get
是读取原子值。
它是响应式的,并且会跟踪读取依赖项。
write 函数中的 get
也是读取 atom 的值,但是没有被跟踪。
此外,它无法读取 Jotai v1 API 中未解析的异步值。
对于异步行为,请参阅 async 文档。
write 函数中的set
是写入原子值。
它将调用目标原子的写入函数。
注意:Atom 配置可以在任何地方创建,但引用相等很重要。
它们也可以动态创建。
要在渲染函数中创建原子,需要使用 useMemo
或 useRef
来获得稳定的引用。 如果对使用 useMemo
或 useRef
进行 memoization 有疑问,请使用 useMemo
。
const Component = ({ value }) => {const valueAtom = useMemo(() => atom({ value }), [value]);// ...};
签名
// 原始 atomfunction atom<Value>(initialValue: Value): PrimitiveAtom<Value>;// 只读 atomfunction atom<Value>(read: (get: Getter) => Value | Promise<Value>): Atom<Value>;// 可写派生 atomfunction atom<Value, Update>(read: (get: Getter) => Value | Promise<Value>,write: (get: Getter, set: Setter, update: Update) => void | Promise<void>): WritableAtom<Value, Update>;// 只写派生 atomfunction atom<Value, Update>(read: Value,write: (get: Getter, set: Setter, update: Update) => void | Promise<void>): WritableAtom<Value, Update>;
initialValue
:原子将返回的初始值,直到它的值被改变。read
:在每次重新渲染时调用的函数。read
的签名是(get) => Value | Promise<Value>
和get
是一个函数,它接受一个原子配置并返回其存储在 Provider 中的值,如下所述。 跟踪依赖关系,因此如果对原子至少使用一次get
,则每当原子值更改时都会重新取值read
。write
:主要用于改变原子值的函数,以便更好地描述; 每当我们调用返回的useAtom
对的第二个值,即useAtom()[1]
时,它就会被调用。 原始原子中此函数的默认值将更改该原子的值。write
的签名是(get, set, update) => void | Promise<void>
。get
与上面描述的类似,但它不跟踪依赖关系。set
是一个函数,它接受一个原子配置和一个新值,然后更新 Provider 中的原子值。update
是我们从下面描述的useAtom
返回的更新函数中接收到的任意值。
const primitiveAtom = atom(initialValue);const derivedAtomWithRead = atom(read);const derivedAtomWithReadWrite = atom(read, write);const derivedAtomWithWriteOnly = atom(null, write);
有两种原子:可写原子和只读原子。 原始原子总是可写的。 如果指定了 write
,派生原子是可写的。 原始原子的 write
相当于 React.useState
的 setState
。
debugLabel
属性
创建的原子配置可以有一个可选属性 debugLabel
。 调试标签用于在调试中显示原子。 有关详细信息,请参阅 调试指南。
注意:虽然调试标签不必是唯一的,但通常建议使它们易于区分。
onMount
属性
创建的原子配置可以有一个可选属性 onMount
。 onMount
是一个接受函数 setAtom
并可选地返回 onUnmount
函数的函数。
onMount
函数在 atom 首次在提供者中使用时被调用,而 onUnmount
在不再使用时被调用。 在一些边缘情况下,一个原子可以被卸载然后立即安装。
const anAtom = atom(1)anAtom.onMount = (setAtom) => {console.log('atom is mounted in provider')setAtom(c => c + 1) // 增加挂载计数return () => { ... } // 返回可选的 onUnmount 函数}
调用 setAtom
函数将调用原子的 write
。 自定义 write
允许改变行为。
const countAtom = atom(1);const derivedAtom = atom((get) => get(countAtom),(get, set, action) => {if (action.type === "init") {set(countAtom, 10);} else if (action.type === "inc") {set(countAtom, (c) => c + 1);}});derivedAtom.onMount = (setAtom) => {setAtom({ type: "init" });};
useAtom
useAtom
hook 用于读取状态中的原子值。
状态可以看作是原子配置和原子值的 WeakMap。
useAtom
hook 以元组形式返回原子值和更新函数,
就像 React 的 useState
一样。
它需要一个使用 atom()
创建的原子配置。