异步 atom
在之前的章节中其实已经出现过了使用异步作为 atom 初始化 read 方法的 atom 示例。这是因为 Jotai 中所有 atom 的创建方法都原生支持使用异步函数作为 atom 的 read 函数和 write 函数。所以异步 atom 的定义与普通 atom 没有什么两样,这里就不再赘述了。
本节所要集中讲述的内容是与异步 atom 相关的一些内容。
异步 atom 的同步使用
在jotai/utils
里提供了一个loadable
函数,可以将一个异步 atom 转换为同步 atom 来使用。loadable
的使用非常简单,它就相当于创建 atom 的atom
函数,直接套在异步 atom 外面即可。
以下示例展示了loadable
的使用方法。
const fetchAtom = atom(async (get) => { ... });
const loadableAtom = loadable(fetchAtom);
const Component = () => {
const [value] = useAtom(loadableAtom);
if (value.state === 'loading') {
return <div>Loading...</div>;
}
if (value.state === 'hasError') {
return <div>Error: {value.error}</div>;
}
if (value.state == 'hasData') {
return <div>{value.data}</div>
}
}
使用loadable
创建的 atom 在使用useAtom
获取其内容的时候,返回的是以下类型的内容:
type LoadableAtomValue = {
state: "loading" | "hasData" | "hasError";
data?: any;
error?: any;
};
结合这个类型,就可以知道上面示例中各个判断的含义了。
更加低阶的向同步 atom 转换
Jotai 在转换异步 atom 方面,除了提供了loadable
函数以外,还提供了一个unwrap
函数。与loadable
不一样,unwrap
不会自动处理异步过程中出现的错误,而是会将其抛出或者使用fallback
函数返回的值代替。unwrap
函数的使用与loadable
函数基本一致,在使用中只需要参考以下unwrap
函数的签名提供相应的参数即可。
// 不提供fallback的版本
function unwrap<Value, Args extends unknown[], Result>(
atom: Writable<Value, Args, Result>
): WritableAtom<Awaited<Value> | undefined, Args, Result>;
// 提供fallback的用于派生atom的版本
function unwrap<Value, Args extends unknown[], Result>(
atom: WritableAtom<Value, Args, Result>,
fallback: (prev?: Awaited<Value>) => PendingValue
): WritableAtom<Awaited<Value> | PendingValue, Args, Result>;
// 提供fallback的用于原始atom的版本
function unwrap<Value, PendingValue>(
atom: Atom<Value>,
fallback: (prev?: Aawaited<Value>) => PendingValue
): Atom<Awaited<Value> | PendingValue>;
在以上函数签名中,Awaited<Value>
都代表一个异步 atom 的执行结果。