|
| 1 | +--- |
| 2 | +title: Suspensive |
| 3 | +description: All in one for React Suspense with Jotai |
| 4 | +nav: 5.04 |
| 5 | +keywords: react, suspense, async, promise, declarative, compound-component, error-boundary |
| 6 | +--- |
| 7 | + |
| 8 | +## Installation |
| 9 | + |
| 10 | +``` |
| 11 | +npm install @suspensive/jotai |
| 12 | +``` |
| 13 | + |
| 14 | +## Why Use? |
| 15 | + |
| 16 | +[@suspensive/jotai](https://suspensive.org/en/docs/jotai/motivation) is utilized for the following reasons: |
| 17 | + |
| 18 | +### Enables Easier and More Intuitive Use of Jotai's Async Atoms |
| 19 | + |
| 20 | +Jotai atoms support asynchronous read/write operations. Async atoms leverage Suspense to handle asynchronous flows, delegating the Promise's pending state to the parent Suspense when an async operation starts. |
| 21 | + |
| 22 | +Props of `<Atom/>` in @suspensive/jotai can be used identically to the interface of `useAtom` in Jotai. Using `<Atom/>` makes it clear internally which atom is being used and intuitively shows how Suspense is triggered at various depths. |
| 23 | + |
| 24 | +```tsx |
| 25 | +import { Atom } from '@suspensive/jotai' |
| 26 | +import { Suspense } from '@suspensive/react' |
| 27 | +import { UserProfile, UserPosts } from '~/components' |
| 28 | +import { userAtom } from '~/atoms' |
| 29 | + |
| 30 | +const MyPage = () => ( |
| 31 | + <Suspense fallback={'pending...'}> |
| 32 | + {/* It's clear which atom is being used and where Suspense is triggered. */} |
| 33 | + <Atom atom={userAtom}>{([data]) => <UserProfile {...data} />}</Atom> |
| 34 | + <Atom atom={userAtom}>{([data]) => <UserPosts {...data} />}</Atom> |
| 35 | + </Suspense> |
| 36 | +) |
| 37 | +``` |
| 38 | + |
| 39 | +### Compatible with Jotai's Extension Libraries |
| 40 | + |
| 41 | +Jotai offers various extension libraries like [tRPC](https://jotai.org/docs/extensions/trpc), [Query](https://jotai.org/docs/extensions/query), and [Cache](https://jotai.org/docs/extensions/cache). Atoms from extension libraries are compatible with @suspensive/jotai's `<Atom/>`, `<SetAtom/>`, `<AtomValue/>`. |
| 42 | + |
| 43 | +Below is an example using the extension library [jotai-tanstack-query](https://github.com/jotaijs/jotai-tanstack-query) introduced in [Query](https://jotai.org/docs/extensions/query#suspense). |
| 44 | + |
| 45 | +```tsx |
| 46 | +import { AtomValue } from '@suspensive/jotai' |
| 47 | +import { Suspense, ErrorBoundary } from '@suspensive/react' |
| 48 | +import { UserProfile } from '~/components' |
| 49 | +import { userQueryAtom } from '~/queries' {/* Used 'atomWithSuspenseQuery' from 'jotai-tanstack-query'. */} |
| 50 | + |
| 51 | +const MyPage = () => ( |
| 52 | + <ErrorBoundary fallback={({ error }) => <>{error.message}</>}> |
| 53 | + <Suspense fallback={'pending...'}> |
| 54 | + <AtomValue atom={userQueryAtom}> {/* Atoms from extension libraries are also compatible. */} |
| 55 | + {({ data: user }) => <UserProfile key={user.id} {...user} />} |
| 56 | + </AtomValue> |
| 57 | + </Suspense> |
| 58 | + </ErrorBoundary> |
| 59 | +) |
| 60 | +``` |
| 61 | + |
| 62 | +## API Reference |
| 63 | + |
| 64 | +### `<Atom/>` |
| 65 | + |
| 66 | +The [Atom](https://suspensive.org/en/docs/jotai/Atom) component provides an interface similar to Jotai's [useAtom](https://jotai.org/docs/core/use-atom#useatom) hook as props, allowing declarative usage. |
| 67 | + |
| 68 | +### `<AtomValue/>` |
| 69 | + |
| 70 | +The [AtomValue](https://suspensive.org/en/docs/jotai/AtomValue) component provides an interface similar to Jotai's [useAtomValue](https://jotai.org/docs/core/use-atom#useatomvalue) hook as props, allowing declarative usage. |
| 71 | + |
| 72 | +### `<SetAtom/>` |
| 73 | + |
| 74 | +The [SetAtom](https://suspensive.org/en/docs/jotai/SetAtom) component provides an interface similar to Jotai's [useSetAtom](https://jotai.org/docs/core/use-atom#usesetatom) hook as props, allowing declarative usage. |
0 commit comments