可加载类
一个 Loadable
对象表示 Recoil 原子 或 选择器 的当前状态。 此状态可能具有可用的值,可能处于错误状态,或者可能仍处于异步解析的挂起状态。 一个 Loadable
具有以下接口
state
: 原子或选择器的当前状态。 可能的值为'hasValue'
、'hasError'
或'loading'
。contents
: 此Loadable
表示的值。 如果状态为hasValue
,则是实际值,如果状态为hasError
,则是抛出的Error
对象,如果状态为loading
,则是值的Promise
。
Loadables 还包含用于访问当前状态的辅助方法。 将此 API 视为不稳定
getValue()
- 用于访问与 React Suspense 和 Recoil 选择器语义匹配的值的方法。 如果状态有值,则返回一个值,如果状态有错误,则抛出该错误,如果状态仍在挂起,则挂起执行或渲染以传播挂起状态。toPromise()
: 返回一个Promise
,该Promise
将在选择器解析后解析。 如果选择器是同步的或已经解析,则它返回一个立即解析的Promise
。valueMaybe()
- 如果可用,则返回该值,否则返回undefined
valueOrThrow()
- 如果可用,则返回该值,否则抛出错误。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;
}
}
创建 Loadables
RecoilLoadable
接口可以被导入来创建您自己的 Loadable
对象。
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);
Loadables 可能表示异步值
// Asynchronously resolves to 123
RecoilLoadable.of(Promise.resolve(123));
类似于 Promise.resolve()
,RecoilLoadable.of()
可以接受字面量值以及 Loadables 或 Promises,这些值将被解包
// All resolve to 'x'
RecoilLoadable.of('x');
RecoilLoadable.of(RecoilLoadable.of('x'));
RecoilLoadable.of(Promise.resolve('x'));
类似地,类似于 Promise.all()
,RecoilLoadable.all()
可以接受 Loadables、Promises 或字面量值的数组
// 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();