atomFamily
引用: https://github.com/pmndrs/jotai/issues/23
使用
atomFamily(initializeAtom, areEqual): (param) => Atom
这将创建一个接受 param
并返回一个原子的函数。
如果它已经创建,它将从缓存中返回。
initializeAtom
是可以返回任何类型原子的函数(atom()
、atomWithDefault()
等)。
请注意,areEqual
是可选的,它判断两个参数是否相等(默认为 Object.is
)。
要重现与 Recoil 的 atomFamily/selectorFamily 类似的行为,
为 areEqual
指定一个 deepEqual 函数。 例如:
import { atom } from "jotai";import deepEqual from "fast-deep-equal";const fooFamily = atomFamily((param) => atom(param), deepEqual);
TypeScript
原子家族类型将从 initializeAtom 中推断出来。 这是原始原子的典型用法。
import type { PrimitiveAtom } from 'jotai'/*** 这里的 atom(is) 返回一个 Primitive Atomic<number>* 而 Primitive Atom<number> 是一个 WritableAtom<number, SetStateAction<number>>*/const myFamily = atomFamily((id: number) => atom(id)).
您可以使用 TypeScript 泛型显式声明参数类型、值和原子的 setState 函数。
atomFamily<Param, Value, Update>(initializeAtom: (param: Param) => WritableAtom<Value, Update>, areEqual?: (a: Param, b: Param) => boolean)atomFamily<Param, Value>(initializeAtom: (param: Param) => Atom<Value>, areEqual?: (a: Param, b: Param) => boolean)
如果要为原始原子显式声明 atomFamily,则需要使用 SetStateAction
。
type SetStateAction<Value> = Value | ((prev: Value) => Value);const myFamily = atomFamily<number, number, SetStateAction<number>>((id: number) => atom(id));
警告:内存泄漏
在内部,atomFamily 只是一个 Map,它的键是一个参数,它的值是一个原子配置。 除非您明确删除未使用的参数,否则会导致内存泄漏。 如果您使用无限数量的参数,这一点至关重要。
有两种方法可以删除参数。
myFamily.remove(param)
允许您删除特 定参数。myFamily.setShouldRemove(shouldRemove)
是注册shouldRemove
函数,它会在您从缓存中获取原子时立即运行。- shouldRemove 是一个函数,它接受两个参数
createdAt
(以毫秒为单位)和param
,并返回一个布尔值。 - 设置
null
将删除之前注册的函数。
- shouldRemove 是一个函数,它接受两个参数
示例
import { atom } from "jotai";import { atomFamily } from "jotai/utils";const todoFamily = atomFamily((name) => atom(name));todoFamily("foo");// 这将创建一个新的 atom('foo'),或者返回已经创建的那个``````jsimport { atom } from "jotai";import { atomFamily } from "jotai/utils";const todoFamily = atomFamily((name) =>atom((get) => get(todosAtom)[name],(get, set, arg) => {const prev = get(todosAtom);return { ...prev, [name]: { ...prev[name], ...arg } };}));
import { atom } from "jotai";import { atomFamily } from "jotai/utils";const todoFamily = atomFamily(({ id, name }) => atom({ name }),(a, b) => a.id === b.id);