Async
所有的原子都支持异步行为,如异步读取或异步写入。然而,这里描述的API可以提供更多的控制。
loadable
如果你不希望异步原子挂起或抛出到错误边界(例如,为了更细粒度的加载和错误逻辑控制),你可以使用 loadable
工具。
它对任何原子都能起作用。只需用 loadable
工具包装你的原子。它返回一个具有三种状态之一的值:loading
,hasData
和 hasError
。
{state: 'loading' | 'hasData' | 'hasError',data?: any,error?: any,}
import { loadable } from "jotai/utils"const asyncAtom = atom(async (get) => ...)const loadableAtom = loadable(asyncAtom)// 不需要被 <Suspense> 元素包裹const Component = () => {const [value] = useAtom(loadableAtom)if (value.state === 'hasError') return <Text>{value.error}</Text>if (value.state === 'loading') {return <Text>Loading...</Text>}console.log(value.data) // Promise的结果return <Text>Value: {value.data}</Text>}
atomWithObservable
参考:https://github.com/pmndrs/jotai/pull/341
使用方法
import { useAtom } from 'jotai'import { atomWithObservable } from 'jotai/utils'import { interval } from 'rxjs'import { map } from 'rxjs/operators'const counterSubject = interval(1000).pipe(map((i) => `#${i}`))const counterAtom = atomWithObservable(() => counterSubject)const Counter = () => {const [counter] = useAtom(counterAtom)return <div>count: {counter}</div>}
atomWithObservable
函数从 rxjs(或类似)的 subject
或 observable
创建一个原子。
其值将是流中最后发出的值。
要使用这个原子,你需要用 <Suspense>
包裹你的组件。查看 guides/async。
初始值
atomWithObservable
接受第二个可选参数 { initialValue }
,该参数允许为原子指定初始值。如果提供了 initialValue
,那么 atomWithObservable
将不会挂起,并且在从 observable 接收到第一个值之前显示初始值。initialValue
可以是一个值,也可以是一个返回值的函数
const counterAtom = atomWithObservable(() => counterSubject, {initialValue: 10,})const counterAtom2 = atomWithObservable(() => counterSubject, {initialValue: () => Math.random(),})
Codesandbox
unwrap
unwrap
工具将把一个异步原子转换为一个同步原子,就像 loadable
一样。
与 loadable
不同,可以配置回退值。
与 loadable
不同,错误不会被处理,而是直接抛出。
unwrap
的使用场景是为了简化派生原子。
这对于 v2 API 特别有用,
因为在读取函数中的 get
不解析 promise。
签名
function unwrap<Value, Args extends unknown[], Result>(anAtom: WritableAtom<Value, Args, Result>,): WritableAtom<Awaited<Value> | undefined, Args, Result>function unwrap<Value, Args extends unknown[], Result, PendingValue>(anAtom: WritableAtom<Value, Args, Result>,fallback: (prev?: Awaited<Value>) => PendingValue,): WritableAtom<Awaited<Value> | PendingValue, Args, Result>function unwrap<Value>(anAtom: Atom<Value>): Atom<Awaited<Value> | undefined>function unwrap<Value, PendingValue>(anAtom: Atom<Value>,fallback: (prev?: Awaited<Value>) => PendingValue,): Atom<Awaited<Value> | PendingValue>
使用方法
import { atom } from 'jotai'import { unwrap } from 'jotai/utils'const countAtom = atom(0)const delayedCountAtom = atom(async (get) => {await new Promise((r) => setTimeout(r, 500))return get(countAtom)})const unwrapped1Atom = unwrap(delayedCountAtom)// 当挂起时,值为 `undefined`const unwrapped2Atom = unwrap(delayedCountAtom, (prev) => prev ?? 0)// 初始值为 `0`,后续更新保持前一个值。