const circularAreaState = selector({
key: "circularArea",
get: ({ get }) => {
return get(lengthState) * get(lengthState) * 3.14;
}
});
selector function 有吃 1 個 Object 參數,這個 Object 有幾個屬性,get 這個 Property 是一個用來計算導出數據( derived data ) 的 function,在這個 get function 它可以在裡面透過 get 取得 atoms
selectors
,當你呼叫 get 時,這個 selector
就會與其它有使用到的 atoms
selectors
建立連結,當有裡面有其中一個狀態被更新時,這個 selector
就會被重新計算。
在我的範例當中,圓面積的 selector
就有依賴到一個長度的 atom
。 circularAreaState
的selector的行為就像是pure function一樣,將 lengthState
作為 input 然後 output 出 circularAreaState
。
useRecoilValue()
作為另一個Recoil 官方 API,它的參數是吃一個 atom
或是 selector
然後回傳出那個state最新的數值,我們不使用 useRecoilState()
拿出 circularArea
,因為 circularArea
是不可被寫入的(它是被 length 這個 atom 計算出來的)Selectors
可以使用 useRecoilValue()
。
CodeSandbox Demo
我們希望有一個長度的狀態,然後根據長度,計算出 正方形面積 與 圓面積。
這個範例我們需用一個 state (長度 length) 作為我們的 atom
,然後另外的這兩個 state 是可以藉由 atom
被計算出來的,而且也依賴於 atom
,因此我們使用 selector
來計算出我們的 square area 跟 circular area。
const lengthState = atom({
key: "length",
default: 0
});
const circularAreaState = selector({
key: "circularArea",
get: ({ get }) => {
return get(lengthState) * get(lengthState) * 3.14;
}
});
const squareAreaState = selector({
key: "squareArea",
get: ({ get }) => {
return get(lengthState) * get(lengthState);
}
});
然後我們在需要使用到這 3 個狀態的地方,透過 useRecoilState()
及 useRecoilValue()
取出。
const [length, setLength] = useRecoilState(lengthState);
const circularArea = useRecoilValue(circularAreaState);
const squareArea = useRecoilValue(squareAreaState);
const handleChange = (e) => {
setLength(e.target.value);
};
而我們渲染的畫面如下:
<div>
<input type="number" onChange={handleChange} />
<div>{` 長度 is ${length}`}</div>
<div>{` 正方形面積 is ${squareArea}`}</div>
<div>{` 圓面積 is ${circularArea}`}</div>
</div>
如此,當我們的 input 更新了 length 時,squareArea 及 circularArea 也會一起被更新。