Loadableクラス
Loadable
オブジェクトは、Recoilのatomまたはselectorの現在の状態を表します。この状態は、値が利用可能であるか、エラー状態であるか、非同期解決がまだ保留中であるかのいずれかです。Loadable
は次のインターフェースを持ちます。
state
: atomまたはselectorの現在の状態。可能な値は'hasValue'
、'hasError'
、または'loading'
です。contents
: このLoadable
によって表される値。状態がhasValue
の場合、実際の値です。状態がhasError
の場合、スローされたError
オブジェクトです。状態がloading
の場合、値のPromise
です。
Loadableには、現在の状態にアクセスするためのヘルパーメソッドも含まれています。 *このAPIは不安定であるとみなしてください*
getValue()
- React SuspenseとRecoil selectorのセマンティクスに一致する値にアクセスするためのメソッド。状態に値がある場合、値を返します。エラーがある場合、そのエラーをスローします。保留中の場合、保留中の状態を伝播するために実行またはレンダリングを中断します。toPromise()
: selectorが解決されたときに解決されるPromise
を返します。selectorが同期しているか、既に解決している場合、すぐに解決されるPromise
を返します。valueMaybe()
- 利用可能な場合に値を返し、それ以外の場合はundefined
を返します。valueOrThrow()
- 利用可能な場合に値を返し、そうでない場合はErrorをスローします。map(callback)
- Loadableの値を変換する関数を取り、変換された値を持つ新しいLoadable
を返します。変換関数は親Loadableの値のパラメータを取得し、新しいLoadableの新しい値を返すことができます。また、スローされたエラーまたはサスペンスも伝播します。コールバック関数は、新しい値、新しい値のPromise
またはLoadable
を返すか、エラーをスローすることができます。このメソッドは、Promiseの.then()
と比較できます。
例
function UserInfo({userID}) {
const userNameLoadable = useRecoilValueLoadable(userNameQuery(userID));
switch (userNameLoadable.state) {
case 'hasValue':
return <div>{userNameLoadable.contents}</div>;
case 'loading':
return <div>Loading...</div>;
case 'hasError':
throw userNameLoadable.contents;
}
}
Loadableの作成
独自のLoadable
オブジェクトを作成するには、RecoilLoadable
インターフェースをインポートできます。
interface RecoilLoadable {
function of<T>(T | Promise<T>, Loadable<T>): Loadable<T>;
function error<T>(mixed): Loadable<T>;
function all(Array<mixed | Loadable<mixed> | Promise<mixed>>): Loadable<Array<mixed>>;
function all({[string]: mixed | Loadable<mixed> | Promise<mixed>}): Loadable<{[string]: mixed}>;
function loading(): Loadable<empty>;
function isLoadable(mixed): boolean;
}
例
RecoilLoadable.of(123);
RecoilLoadable.error(new Error('ERROR'));
RecoilLoadable.all([
RecoilLoadable.of(1),
RecoilLoadable.of(10),
RecoilLoadable.of(100),
]).map(([a, b, c]) => a+b+c);
Loadableは非同期値を表す場合があります。
// Asynchronously resolves to 123
RecoilLoadable.of(Promise.resolve(123));
Promise.resolve()
と同様に、RecoilLoadable.of()
は、アンパックされるLoadableやPromiseだけでなく、リテラル値も受け入れることができます。
// All resolve to 'x'
RecoilLoadable.of('x');
RecoilLoadable.of(RecoilLoadable.of('x'));
RecoilLoadable.of(Promise.resolve('x'));
同様に、Promise.all()
と同様に、RecoilLoadable.all()
は、Loadable、Promise、またはリテラル値の配列を受け入れることができます。
// Resolves to [1, 2, 3]
RecoilLoadable.all([1, RecoilLoadable.of(2), Promise.resolve(3)]);
// Resolves to {value: 1, loadable: 2, promise: 3}
RecoilLoadable.all({
value: 1,
loadable: RecoilLoadable.of(2),
promise: Promise.resolve(3),
});
// Never resolves
RecoilLoadable.loading();