Derived Atoms and Async Atoms
Compose derived atoms from other atoms and create async atoms that integrate with Suspense.
Derived Atoms and Async Atoms is a free React Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Read-Only Derived Atoms
Create a derived atom by passing a getter function: const doubleAtom = atom(get => get(countAtom) * 2). This atom has no stored value; it recomputes whenever countAtom changes.
Derived atoms are always up-to-date without any manual synchronization. They are the Jotai equivalent of computed properties.
Automatic Dependency Tracking
Jotai tracks which atoms were accessed inside the getter function and automatically re-evaluates the derived atom when any of them change. You do not declare dependencies explicitly.
If the getter calls get(atomA) and get(atomB), the derived atom updates whenever either atomA or atomB changes.
Writable Derived Atoms
A writable derived atom has both a getter and a setter: atom(get => get(baseAtom).toUpperCase(), (get, set, newValue) => set(baseAtom, newValue.toLowerCase())). Reading gives the transformed value; writing transforms and stores back.
This pattern implements two-way data transformation without exposing the base atom directly.
Async Atoms with Promises
The getter function can be async: const userAtom = atom(async get => { const id = get(userIdAtom); return await fetchUser(id); }). Jotai accepts Promises from atom getters natively.
When userIdAtom changes, Jotai automatically re-runs the async getter and the consuming component suspends during the fetch.
Async Atoms and React Suspense
Async atoms integrate seamlessly with React Suspense. Wrap the consuming component in a Suspense boundary with a fallback. The component suspends while the Promise is pending and renders when it resolves.
This eliminates manual loading state management in the component: no isLoading flag, no useEffect for data fetching.
loadable: Opt Out of Suspense
Import loadable from jotai/utils. Wrap an async atom: const loadableUserAtom = loadable(userAtom). Components reading loadableUserAtom receive {state: 'loading'}, {state: 'hasData', data: user}, or {state: 'hasError', error} without suspending.
Use loadable when you need to render a custom loading state inline rather than relying on a Suspense boundary.
Resetting Atoms
The atomWithReset utility from jotai/utils creates an atom that can be reset to its initial value using the RESET symbol. This is cleaner than manually tracking and re-applying the initial value.
In forms, reset all field atoms on submit or cancel by calling each setter with RESET in a single handler.
Chaining Atoms
A derived atom can read from multiple other atoms: const summaryAtom = atom(get => ({ user: get(userAtom), settings: get(settingsAtom), count: get(countAtom) })). This creates a single stable reference that updates when any dependency changes.
Components that only need the summary subscribe to summaryAtom rather than all three individual atoms.
Conditional Atoms
Derived atoms can conditionally read different atoms: const activeDataAtom = atom(get => get(modeAtom) === 'A' ? get(dataAAtom) : get(dataBAtom)). When modeAtom switches, the derived atom switches its data source automatically.
Jotai re-subscribes to the correct atom on each evaluation, ensuring no stale data from the inactive branch.
Async Atom Error Handling
If an async atom's getter throws or rejects, the error propagates to the nearest React error boundary when used with Suspense. With loadable, the error appears in the state.error field for inline handling.
Always pair async atoms with either an ErrorBoundary or a loadable wrapper in production code.
Derived Atom Performance
Derived atoms memoize their last result. If all dependency atoms return the same values as the previous evaluation, the derived atom returns the same reference and no downstream re-renders occur.
For expensive derivations (large array transforms), this memoization provides significant performance benefits without any additional configuration.
Async Atom and Suspense Integration
What happens to a component reading an async atom while its Promise is pending?
Lesson Recap
Derived atoms compute values from other atoms using getter functions with automatic dependency tracking. Async atoms use async getters and integrate with React Suspense by default; use loadable from jotai/utils to opt out and handle loading/error states inline.
Writable derived atoms enable two-way transformations, and conditional atoms dynamically switch data sources based on other atom values.
Frequently asked questions
Is the “Derived Atoms and Async Atoms” lesson free?
Yes — the full text of “Derived Atoms and Async Atoms” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.
What will I learn in “Derived Atoms and Async Atoms”?
Compose derived atoms from other atoms and create async atoms that integrate with Suspense. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start React Academy?
No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Derived Atoms and Async Atoms” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this React Academy lesson?
Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.