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 { Atom } from '@suspensive/jotai'
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 { Suspense } from '@suspensive/react'
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 { Atom } from '@suspensive/jotai'
import { Suspense } from '@suspensive/react'
import { shoppingCartAtom } from '~/atoms'
// ์ด ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ์
์ฅ์์ ShoppingCart๋ผ๋ ์ด๋ฆ๋ง์ผ๋ก ๋ด๋ถ์ ์ผ๋ก ์ด๋ค Atom์ ์ฌ์ฉํ๊ณ , Suspense๋ฅผ ๋ฐ์ํ ์ง ์์ํ๊ธฐ ์ด๋ ต์ต๋๋ค.
const ShoppingCart = () => {
const [data] = useAtom(shoppingCartAtom)
return (
<>
{data.map((item) => (
<ShoppingItem key={item.id} {...item} />
))}
</>
)
}