跳至主要內容

selectorFamily(options)

傳回會傳回唯讀 RecoilValueReadOnly 或可寫入 RecoilState 篩選器的函數。

selectorFamily 是一種功能強大的模式,類似於 selector,但可讓您傳遞參數給 selectorgetset 回呼。selectorFamily() 工具程式傳回一個函數,可呼叫此函數並搭配使用者定義的參數,並傳回篩選器。每個獨特的參數值都會傳回相同備忘 memoize 的篩選器執行個體。


唯讀篩選器類別

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)會有問題。要可序列化,它必須是下列其中一項:

  • 原始值
  • 可序列化值的陣列、物件、MapSet
  • 包含 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 屬性允許您組態建構家族的個別選擇器的快取行為。這個屬性對於縮減具有大量選擇器的應用程式的記憶體很有用,這些選擇器具有大量變動的依賴項。請參閱 選擇器快取原則組態文件