Recoilのselector
selector内では必ず一つ以上のatomを呼ぶことになるが、これらのうちどれか一つが更新されたら実行される
selectorの中でselectorを呼べる
つまりcontextも使わず、viewのprops drillingもせずにpropsの伝搬ができる
selectorの利用者はatomと全く同じインターフェースで利用できる
pure atomかどうかを気にしなくていい
定義
key
ユニーク
get
reducerっぽいやつをかく
set
writeする処理を書く
これはoptional
型もしっかり効く
setを定義していない場合はRecoilValueReadOnly型になる
従ってuseRecoilStateなどで使おうとするとtype errorになる
code:ts
const A = () => {
const calc = selector({...});
const value = useRecoilValue(calc)
return (..)
}
calcのselector内で使われているatomの値が更新されるだけではAは再描画されない
ちゃんとslector内でcalcが更新された場合のみAが再描画される
割とあらゆるものをatomにして、それを組み合わせてslectorをやっていくという感じがある
故に、引数の存在がそこまで必須にならないというか
その引数にしたいものもatomにしろや、という感じか
その場合は、以下のいずれかになるってことか
更新したい対象がおかしい。元のatomを更新すべきなのでは
その引数にしたいものもatomにする
selectorを使わずatom + custom hooksにする
↑例がないと何を言ってるかわからなくなりそうmrsekut.icon
getに引数渡せないんだな
それをやるならcustom hookにするしかないのか
ちょっと意味が違いそう
配列のatomから、indexで一つ抜き出してほしかった
indexが別のatomならいけるが
familyを使って、逆でもいいが
setって何に対してsetするの?
何の値を更新している?
元のatom
元のatomを更新しているだけで、自分自身を更新しているわけではない
非同期なselector
各フィールドをatomで作って
そのまとまりをselectorで作る
みたいな使い方ができる
selectorを使うタイミングがいまいちわからない
それはatomが大きいからだったりするかも
docsの上部にtodoリストでのselectorの例がある atomをcustom hooksで囲って使うのこととの違いは?
selectorの使いみち、具体例
recoilのloadableのように、fetchの状態をselectorで表現
code:ts
export const accountUiState = selector<AccountUiState>({
key: "accountUiState",
get: ({ get }) => {
const { account, isLoading, error } = get(accountAtom);
if (isLoading) return { status: "Loading" };
if (error) return { status: "ShowError", error: error };
if (account) return { status: "LoggedIn", account: account };
return { status: "NotLoggedIn" };
},
});
「atomの状態変化」は、atomに密結合な概念なので、selectorでやるのは正しい気がする
Docsのこういう例とか、custom hookとして作ってしまいがち
まあ普通にselectorは値なので、値を定義したい!と発想できるならselectorで定義すればいいmrsekut.icon
「値の変更」に着目するのか?
code:ts
const filteredTodoListState = selector({
key: 'filteredTodoListState',
get: ({get}) => {
const filter = get(todoListFilterState);
const list = get(todoListState);
switch (filter) {
case 'Show Completed':
return list.filter((item) => item.isComplete);
case 'Show Uncompleted':
return list.filter((item) => !item.isComplete);
default:
return list;
}
},
});
custom hooksを作る感覚でselectorを量産するイメージだろうか?mrsekut.icon
atom→selector→custom hooksというレイヤーがあるように感じる
この時、custom hooksはrecoilというlibraryに依存しないものになる