JotaiJotai

상태
React를 위한 기본적이고 유연한 상태 관리

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 { 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`이며, 이후 업데이트 시 이전 값을 유지함

초기값

atomWithObservable은 두 번째 선택적 매개변수로 { initialValue }를 받습니다. 이 매개변수를 통해 아톰의 초기값을 지정할 수 있습니다. initialValue가 제공되면 atomWithObservable은 서스펜드되지 않고, 옵저버블로부터 첫 번째 값을 받기 전에 초기값을 보여줍니다. initialValue는 값 자체일 수도 있고, 값을 반환하는 함수일 수도 있습니다.

const counterAtom = atomWithObservable(() => counterSubject, {
initialValue: 10,
})
const counterAtom2 = atomWithObservable(() => counterSubject, {
initialValue: () => Math.random(),
})

Stackblitz

unwrap

unwrap 유틸리티는 loadable처럼 비동기 아톰을 동기 아톰으로 변환합니다.
loadable과 달리, fallback 값을 설정할 수 있습니다.
loadable과 달리, 오류는 처리되지 않고 그대로 던져집니다.

unwrap의 사용 사례는 아톰을 파생시키는 작업을 쉽게 하는 것입니다.
이는 특히 v2 API에서 유용합니다.
왜냐하면 read 함수 내의 get은 Promise를 resolve하지 않기 때문입니다.

시그니처

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>