Atom
Atom 컴포넌트는 Jotai의 useAtom 훅과 동일한 인터페이스를 Props로 제공하며 선언적으로 사용할 수 있습니다.
props.atom
Jotai의 atom을 그대로 사용할 수 있습니다.
import { Atom } from '@suspensive/jotai'
import { atom } from 'jotai'
const countAtom = atom(1)
const Example = () => (
<Atom atom={countAtom}>
{([count, setCount]) => (
<>
<div>count: {count}</div>
<button onClick={() => setCount(count + 1)}>+1</button>
</>
)}
</Atom>
)
Async Atom일 경우 프로미스(Promise)가 해결(resolve) 되기 전까지, 부모의 Suspense에게 Promise의 pending 상태를 위임합니다.
import { Atom } from '@suspensive/jotai'
import { Suspense } from '@suspensive/react'
import { atom } from 'jotai'
const countAtom = atom(1)
const asyncDoubleCountAtom = atom(async (get) => {
await delay(2000)
return get(countAtom) * 2
})
const Example = () => (
<Suspense fallback={'pending...'}>
<Atom atom={asyncDoubleCountAtom}>{([count]) => <>count: {count}</>}</Atom>
</Suspense>
)
동기
상위 컴포넌트에서 useAtom이 명확하게 드러나지 않습니다. 하위에 선언된 컴포넌트가 내부적으로 어떤 Atom을 사용하고, Suspense를 발생할지 예상하기 어렵습니다.
// payment/page.tsx
import { Suspense } from '@suspensive/react'
import { UserInfo, ShoppingCart } from '~/components'
const PaymentPage = () => (
<Suspense fallback={'pending...'}>
{/* UserInfo의 내부적으로 Suspense를 발생시키는 Async Atom을 사용하는지 예상하기 어렵습니다. */}
<UserInfo />
{/* ShoppingCart의 내부적으로 Suspense를 발생시키는 Async Atom을 사용하는지 예상하기 어렵습니다. */}
<ShoppingCart />
</Suspense>
)
// payment/components/UserInfo.tsx
import { useAtomValue } from '@suspensive/jotai'
import { UserAddress } from '~/components'
import { userAsyncAtom } from '~/atoms'
// 이 컴포넌트를 사용하는 입장에서 UserInfo라는 이름만으로 내부적으로 어떤 Atom을 사용하고, Suspense가 발생할지 예상하기 어렵습니다.
const UserInfo = () => {
const data = useAtomValue(userAsyncAtom)
return <UserAddress {...data} />
}
// payment/components/ShoppingCart.tsx
import { useAtom } from 'jotai'
import { ShoppingItem } from '~/components'
import { shoppingCartAtom } from '~/atoms'
// 이 컴포넌트를 사용하는 입장에서 ShoppingCart라는 이름만으로 내부적으로 어떤 Atom을 사용하고, Suspense가 발생할지 예상하기 어렵습니다.
const ShoppingCart = () => {
const [data] = useAtom(shoppingCartAtom)
return (
<>
{data.map((item) => (
<ShoppingItem key={item.id} {...item} />
))}
</>
)
}
수정된 날짜: