Reading and Writing Atoms with useAtom
Use useAtom, useAtomValue, and useSetAtom to read and update atoms across the component tree.
Reading and Writing Atoms with useAtom is a free React Academy lesson on CoddyKit — lesson 2 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.
useAtom: The Primary Hook
useAtom(someAtom) returns [value, setter], mirroring the useState API. The value is the current atom state; the setter updates it. Use this when a component both reads and writes the atom.
The setter accepts either a new value or an updater function: setCount(c => c + 1).
useAtomValue: Read-Only Access
useAtomValue(someAtom) returns only the current value, with no setter. Use this in display-only components that read state but never modify it.
Because the component does not hold a setter reference, the intent is clearly documented in code: this component is a pure reader.
useSetAtom: Write-Only Access
useSetAtom(someAtom) returns only the setter function. Critically, it does not subscribe the component to the atom's value. The component never re-renders when the atom changes.
Use this for action-only components like buttons that dispatch state changes but do not display any derived UI.
Why useSetAtom Matters for Performance
A component that calls useSetAtom(countAtom) to increment a counter will never re-render when countAtom changes, because it has no value subscription. Only the component displaying the count re-renders.
This is a simple but powerful optimization: decouple writers from readers to prevent cascading re-renders.
atomWithStorage for Persistence
Import atomWithStorage from jotai/utils. Use it exactly like atom() but pass a storage key as the first argument: atomWithStorage('theme', 'light'). The atom automatically syncs to localStorage.
On page reload, the atom hydrates from localStorage. All components reading the atom pick up the persisted value immediately.
Resetting atomWithStorage
The RESET symbol from jotai/utils can be passed to the setter of an atomWithStorage atom: setter(RESET). This clears the localStorage entry and resets the atom to its initial value.
This is useful for logout flows or "reset to defaults" buttons in settings pages.
Atom Families with atomFamily
atomFamily from jotai/utils creates a factory that returns a parameterized atom. For example, atomFamily(id => atom(null)) creates a separate atom for each unique id passed.
This is ideal for per-item state like selectedAtom(itemId) or expandedAtom(rowId) without managing a single large map atom.
Atom Family Cleanup
Atom families can grow unbounded if IDs accumulate. Use atomFamily.setShouldRemove((createdAt, param) => ...) to define a cleanup predicate that Jotai calls when deciding to evict stale family members.
For lists where items are added and removed, always clean up atom family entries when items are deleted to avoid memory leaks.
Jotai DevTools
The jotai-devtools package provides a visual panel listing all active atoms and their current values. Install it, wrap your app in DevTools, and inspect atom state in real time.
Each atom update is logged with the previous and next value, making debugging complex atom interactions straightforward.
Selective Re-Rendering Example
In a large list, a ListContainer component can use useSetAtom(selectedIdAtom) to update selection without subscribing to selectedIdAtom. Only the individual ListItem components that call useAtomValue(selectedIdAtom) re-render when the selection changes.
This pattern scales well: adding thousands of list items does not slow down selection updates.
Combining the Three Hooks
Choose the hook that matches your component's need: useAtomValue for pure display, useSetAtom for pure actions, and useAtom when you need both. This intentional API design makes component responsibility clear at a glance.
A form field component typically uses useAtom; a submit button uses useSetAtom; a label displaying a count uses useAtomValue.
useSetAtom vs useAtom
What is the key advantage of using useSetAtom instead of useAtom?
Lesson Recap
useAtom gives both value and setter; useAtomValue gives only the value (read subscriptions); useSetAtom gives only the setter (no re-render on value change). atomWithStorage persists to localStorage with RESET support, and atomFamily creates per-parameter atoms for dynamic lists.
Choosing the right hook minimizes unnecessary re-renders and makes component intent explicit.
Frequently asked questions
Is the “Reading and Writing Atoms with useAtom” lesson free?
Yes — the full text of “Reading and Writing Atoms with useAtom” 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 “Reading and Writing Atoms with useAtom”?
Use useAtom, useAtomValue, and useSetAtom to read and update atoms across the component tree. 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 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Reading and Writing Atoms with useAtom” 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.
All lessons in this course
- Atoms: The Unit of State in Jotai
- Reading and Writing Atoms with useAtom
- Derived Atoms and Async Atoms
- Jotai vs Zustand vs Context: When to Use Which