Skip to Content
๐Ÿ‘€ Suspensive v3์—์„œ์˜ ๋ณ€๊ฒฝ์„ ํ™•์ธํ•˜์„ธ์š”. ๋”๋ณด๊ธฐ
๋ฌธ์„œ๋ณด๊ธฐ@suspensive/jotai<Atom/>

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} /> ))} </> ) }
์ˆ˜์ •๋œ ๋‚ ์งœ: