--- title: Async description: This doc describes about the behavior with async. nav: 1.03 --- Async support is first class in jotai. It fully leverages React Suspense. > Technically, Suspense usage other than React.lazy is still unsupported / undocumented in React 17. If this is blocking, check out [guides/no-suspense](../guides/no-suspense.mdx). ## Suspense To use async atoms, you need to wrap your component tree with ``. If you have ``, place at least one `` inside the ``. ```jsx const App = () => ( ) ``` Having more ``s in the component tree is also possible. ## Async read atom The `read` function of an atom can return a promise. It will suspend and re-render once the promise fulfills. Most importantly, useAtom only returns a resolved value. ```js const countAtom = atom(1) const asyncCountAtom = atom(async (get) => get(countAtom) * 2) // even though the read function returns a promise, const Component = () => { const [num] = useAtom(asyncCountAtom) // `num` is guaranteed to be a number. } ``` An atom becomes async not only if the atom read function is async, but also if one or more of its dependencies are async. ```js const anotherAtom = atom((get) => get(asyncCountAtom) / 2) // even though this atom doesn't return a promise, // it's a read async atom because `asyncCountAtom` is async. ```
Async write atom behavior until v1.3.9 (This is no longer the case since v1.4.0.) ## Async write atom Async write atoms are another kind of async atom. When the `write` function of atom returns a promise, it may suspend. This happens if the atom is used directly with useAtom, regardless of its value. (The atom value can be `null`.) ```js const countAtom = atom(1) const asyncIncrementAtom = atom(null, async (get, set) => { // await something set(countAtom, get(countAtom) + 1) }) const Component = () => { const [, increment] = useAtom(asyncIncrementAtom) // it will suspend while `increment` is pending. } ``` > There's no way to know as of now if an atom suspends because of `read` or `write`. ### Triggering `Suspense` fallback of write atom This section applies only for "async write atom" not "async read atom", which works differently with `Suspense`. **A write atom will trigger the `Suspense` fallback if:** * the atom's write argument (2nd one) is async * the awaited call is made directly, and not from inside another containing function This _will_ trigger the `Suspense` fallback: ```ts const writeAtom = atom(null, async (get, set) => { const response = await new Promise((resolve, _reject) => { setTimeout(() => { resolve('some returned value') }, 2000) }) set(somePrimitiveAtom, 'The returned value is: ' + response) }) ``` This _will not_ trigger the `Suspense` fallback: ```ts const writeAtom = atom(null, (get, set) => { const getResponse = async () => { const response = await new Promise((resolve, _reject) => { setTimeout(() => { resolve('some returned value') }, 2000) }) set(somePrimitiveAtom, 'The returned value is: ' + response) } getResponse() }) ``` But **_both_** of the above will still set `somePrimitiveAtom` to the correct values.