Closed5
RecoilのAtomでdefault: undefinedを回避したい
Recoilでは、通常ステートを初期化する場合は以下のようにする。
const sampleState = atom<string | undefined>({
key: 'sample',
default: undefined,
effects: [({ setSelf }) => setSelf('sample')],
});
const useSample = () => {
const [sample, setSample] = useRecoilState(sampleState);
// 各種処理
}
上記のような場合は特に処理がないから直接default: 'sample'
のようにできる。
一方で、たとえばAPI経由で値を取得して初期値を格納したいなど、何らかの処理を噛ませたい場合はいったんdefault: undefined
として後から値を格納するように記述されているのを多く見かける。
ただし、一度でもundefiend
を許容してしまえば後々の全ての処理でundefiend
を考慮する必要が出てくる。
毎回毎回分岐を考慮するのは非常に面倒なので、初期値から計算した値を入れたいけどどうしようかなという話。
……書いてて思ったけど、これselectorでいけるのでは?
求める値が何らかの値に依存し、かつ常に求められる値であるならselectorで問題なさそう。
一方で、ログインユーザーのように状況によっては求められない値を格納したい場合、当然だけどその状況を想定した処理を考える必要がある。
値を求められない場合はエラーを投げてどこかの階層でハンドリングできたらうまくできそうだけど、そう簡単にいくかな……?
却って労力が増えそう。
痒いところに手が届きそうに見える。
const hogeState = atom<string>({
key: 'hoge',
default: errorSelector('初期化してください。'),
});
const Fuga = () => {
const setHoge = useSetRecoilState(hogeState); // セッターのみ呼び出す
const [viewHoge, setViewHoge] = useState(false);
const onPress = () => {
setHoge('hoge');
setViewHoge(true);
};
return (
<>
<Button onPress={onPress} title="View Hoge" />
{viewHoge && <ViewHoge />}
</>
);
};
const ViewHoge = () => {
const hoge = useRecoilValue(hogeState);
return <Text>{hoge}</Text>;
}
これでいける。
useSetRecoilState(hogeState)
としているのは、値がerrorSelector
のまま呼び出すとエラーになるため。
同じようなやり方でSelectorも利用できることを確認した。
const hogeState = atom<string | undefined>({
key: 'hoge',
default: undefined,
});
const fugaState = selector<string>({
key: 'fuga',
get: ({ get }) => {
const hoge = get(hogeState);
return typeof hoge === 'undefined'
? errorSelector('hogeが未定義です。')
: hoge;
}
})
const Fuga = () => {
const [hoge, setHoge] = useRecoilState(hogeState);
return (
<>
<Button onPress={() => setHoge('hoge')} title="Set Hoge" />
{hoge && <ViewHoge />}
</>
);
};
const ViewHoge = () => {
const hoge = useRecoilValue(fugaState);
return <Text>{hoge}</Text>;
}
これでもいける。はず。
このスクラップは2022/07/30にクローズされました