扫码一下
查看教程更方便
selectorfamily(options)
返回一个函数,该函数返回一个只读的 recoilvaluereadonly 或者可写的 recoilstate selector。
selectorfamily
是一个功能强大的模式,类似于 selector,但允许你将参数传递给 selector
的 get
和 set
回调。selectorfamily() 工具函数的返回值是一个函数,该函数可以使用自定义的参数进行调用并会翻译一个 selector。对每个唯一参数值,该函数都将返回相同的 selector 实例。
function selectorfamily({
key: string,
get: parameter => ({get: getrecoilvalue}) => promise | recoilvalue | t,
dangerouslyallowmutability?: boolean,
}): parameter => recoilvaluereadonly
function selectorfamily({
key: string,
get: parameter => ({get: getrecoilvalue}) => promise | recoilvalue | t,
set: parameter => (
{
get: getrecoilvalue,
set: setrecoilvalue,
reset: resetrecoilvalue,
},
newvalue: t | defaultvalue,
) => void,
dangerouslyallowmutability?: boolean,
}): parameter => recoilstate
这里
type valueorupdater = t | defaultvalue | ((prevvalue: t) => t | defaultvalue);
type getrecoilvalue = (recoilvalue) => t;
type setrecoilvalue = (recoilstate, valueorupdater) => void;
type resetrecoilvalue = (recoilstate) => void;
selectorfamily
本质上提供了从参数到选择器的映射。因为参数通常是使用族在调用站点上生成的,并且我们希望等效的参数重新使用相同的基础选择器,所以默认情况下它使用值相等而不是引用相等。(有一个不稳定的 api 可以调整此行为)。这对可用于参数的类型施加了限制。请使用原始类型或可以序列化的对象。recoil 使用可以支持对象和数组的自定义序列化程序,某些容器(例如es6 sets和maps)不改变对象键顺序,支持symbols、iterables,并可用 tojson 属性来进行自定义序列化(例如类似不可变容器之类的库)。在参数中使用函数或可变对象(如 promises)都有可能造成问题。
const mynumberstate = atom({
key: 'mynumber',
default: 2,
});
const mymultipliedstate = selectorfamily({
key: 'mymultipliednumber',
get: (multiplier) => ({get}) => {
return get(mynumberstate) * multiplier;
},
// 可选 set
set: (multiplier) => ({set}, newvalue) => {
set(mynumberstate, newvalue / multiplier);
},
});
function mycomponent() {
// 默认为 2
const number = userecoilvalue(mynumberstate);
// 默认为 200
const multipliednumber = userecoilvalue(mymultipliedstate(100));
return ...;
}
selector 族对于将参数传递给查询也很有用。注意,使用 selector 来抽象这样的查询仍然应该是 “纯” 函数,对于给定的一组输入值和依赖值,它们总是返回相同的结果。
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 ...;
}
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 (
<>
);
}
const component2 = () => {
const [value, onchange] = userecoilstate(formfieldstate('field2'));
return (
);
}