selectorFamily(options)
返回一个函数,该函数返回一个只读的 RecoilValueReadOnly
或可写的 RecoilState
选择器。
selectorFamily
是一种强大的模式,类似于 selector
,但允许您将参数传递给 selector
的 get
和 set
回调。selectorFamily()
工具返回一个函数,该函数可以使用用户定义的参数调用并返回一个选择器。每个唯一的参数值将返回相同的已记忆选择器实例。
只读选择器族
function selectorFamily<T, P: Parameter>({
key: string,
get: P => ({
get: GetRecoilValue
getCallback: GetCallback<T>,
}) =>
T | Promise<T> | Loadable<T> | WrappedValue<T> | RecoilValue<T>,
dangerouslyAllowMutability?: boolean,
}): P => RecoilValueReadOnly<T>
可写选择器族
function selectorFamily<T, P: Parameter>({
key: string,
get: P => ({
get: GetRecoilValue
getCallback: GetCallback<T>,
}) =>
T | Promise<T> | Loadable<T> | WrappedValue<T> | RecoilValue<T>,
set: P => (
{
get: GetRecoilValue,
set: SetRecoilValue,
reset: ResetRecoilValue,
},
newValue: T | DefaultValue,
) => void,
dangerouslyAllowMutability?: boolean,
cachePolicy_UNSTABLE?: CachePolicy,
}): P => RecoilState<T>
其中
type ValueOrUpdater<T> = T | DefaultValue | ((prevValue: T) => T | DefaultValue);
type GetRecoilValue = <T>(RecoilValue<T>) => T;
type SetRecoilValue = <T>(RecoilState<T>, ValueOrUpdater<T>) => void;
type ResetRecoilValue = <T>(RecoilState<T>) => void;
type GetCallback<T> =
<Args, Return>(
callback: ({node: RecoilState<T>, ...CallbackInterface}) => (...Args) => Return,
) => (...Args) => Return;
type CachePolicy =
| {eviction: 'lru', maxSize: number}
| {eviction: 'keep-all'}
| {eviction: 'most-recent'};
key
- 用于在内部标识原子的唯一字符串。此字符串应该相对于整个应用程序中的其他原子和选择器是唯一的。get
- 一个函数,它传递一个命名回调的对象,返回选择器的值,与selector()
接口相同。它被一个函数包装,该函数传递了从调用选择器族函数传递的参数。set?
- 一个可选函数,它将在提供时生成可写的选择器。它应该是一个函数,它接受一个命名回调的对象,与selector()
接口相同。它再次被另一个函数包装,该函数从调用选择器族函数获取参数。cachePolicy_UNSTABLE
- 定义构成族的各个选择器的内部选择器缓存的行为(它不控制存储在族中的选择器数量)。可以用于控制具有大量更改依赖关系的选择器的应用程序中的内存占用量。eviction
- 可以设置为lru
(这需要设置maxSize
)、keep-all
(默认)或most-recent
。当缓存的大小超过maxSize
时,lru
缓存将从选择器缓存中逐出最不经常使用的值。keep-all
策略意味着所有选择器依赖项及其值将无限期地存储在选择器缓存中。most-recent
策略将使用大小为 1 的缓存,并将仅保留最近保存的一组依赖项及其值。- 请注意,与
lru
一起使用的maxSize
属性不控制族本身的最大大小,它仅控制构成族的各个选择器中使用的逐出策略。 - 请注意,缓存基于包含所有依赖项及其值的键存储选择器的值。这意味着内部选择器缓存的大小取决于选择器值的大小以及所有依赖项的唯一值的数量。
- 请注意,默认逐出策略(目前为
keep-all
)可能会在将来发生更改。
selectorFamily()
本质上提供了从参数到选择器的映射。您只需要为原子族提供一个键,它将为每个底层选择器生成一个唯一的键。
参数类型
type Primitive = void | null | boolean | number | string;
interface HasToJSON {
toJSON(): Parameter;
}
type Parameter =
| Primitive
| HasToJSON
| $ReadOnlyArray<Parameter>
| $ReadOnly<{[string]: Parameter}>
| $ReadOnlySet<Parameter>
| $ReadOnlyMap<Parameter, Parameter>;
您可以使用作为族 Parameter
的类型存在限制。它们可能在不同的调用点生成,我们希望等效的参数引用相同的底层选择器。因此,参数使用值相等性进行比较,并且必须是可序列化的。在参数中使用函数或可变对象(例如 Promise)会有问题。要可序列化,它必须是以下之一
- 一个基本值
- 可序列化值的数组、对象、
Map
或Set
- 包含一个
toJSON()
方法,该方法返回一个可序列化的值,类似于JSON.stringify()
示例
const myNumberState = atom({
key: 'MyNumber',
default: 2,
});
const myMultipliedState = selectorFamily({
key: 'MyMultipliedNumber',
get: (multiplier) => ({get}) => {
return get(myNumberState) * multiplier;
},
// optional set
set: (multiplier) => ({set}, newValue) => {
set(myNumberState, newValue / multiplier);
},
});
function MyComponent() {
// defaults to 2
const number = useRecoilValue(myNumberState);
// defaults to 200
const multipliedNumber = useRecoilValue(myMultipliedState(100));
return <div>...</div>;
}
异步查询示例
选择器族对于将参数传递给查询也非常有用。请注意,使用选择器来抽象像这样的查询仍然应该是“纯”函数,对于给定的一组输入和依赖项值始终返回相同的结果。有关更多示例,请参阅 本指南。
const myDataQuery = selectorFamily({
key: 'MyDataQuery',
get: (queryParameters) => async ({get}) => {
const response = await asyncDataRequest(queryParameters);
if (response.error) {
throw response.error;
}
return response.data;
},
});
function MyComponent() {
const data = useRecoilValue(myDataQuery({userID: 132}));
return <div>...</div>;
}
解构示例
const formState = atom({
key: 'formState',
default: {
field1: "1",
field2: "2",
field3: "3",
},
});
const formFieldState = selectorFamily({
key: 'FormField',
get: field => ({get}) => get(formState)[field],
set: field => ({set}, newValue) =>
set(formState, prevState => ({...prevState, [field]: newValue})),
});
const Component1 = () => {
const [value, onChange] = useRecoilState(formFieldState('field1'));
return (
<>
<input value={value} onChange={onChange} />
<Component2 />
</>
);
}
const Component2 = () => {
const [value, onChange] = useRecoilState(formFieldState('field2'));
return (
<input value={value} onChange={onChange} />
);
}
缓存策略配置
cachePolicy_UNSTABLE
属性允许您配置构成族的各个选择器的缓存行为。此属性对于减少具有大量选择器(这些选择器具有大量更改依赖项)的应用程序中的内存非常有用。请参阅 选择器缓存策略配置文档。