Skip to main content
Module

x/jotai/docs/introduction.mdx

👻 Primitive and flexible state management for React
Go to Latest
File
---title: Introductiondescription: How to use Jotainav: 0---
`npm install jotai` or `yarn add jotai`
Jotai is pronounced "joe-tie" and means "state" in Japanese.
You can try live demos here:[Demo 1](https://codesandbox.io/s/jotai-demo-47wvh) |[Demo 2](https://codesandbox.io/s/jotai-demo-forked-x2g5d).
#### How does Jotai differ from Recoil?
- Minimalistic API- No string keys- TypeScript oriented### First create a primitive atom
An atom represents a piece of state. All you need is to specify an initialvalue, which can be a primitive value like a string, number, object orarray. You can create as many primitive atoms as you like.
```jsximport { atom } from 'jotai'
const countAtom = atom(0)const countryAtom = atom('Japan')const citiesAtom = atom(['Tokyo', 'Kyoto', 'Osaka'])const mangaAtom = atom({ 'Dragon Ball': 1984, 'One Piece': 1997, Naruto: 1999 })```
### Use the atom in your components
Use an atom like you'd use `React.useState`:
```jsximport { useAtom } from 'jotai'
function Counter() { const [count, setCount] = useAtom(countAtom) return ( <h1> {count} <button onClick={() => setCount(c => c + 1)}>one up</button>```
### Create derived atoms with computed values
A new read-only atom can be created from existing atoms by passing a readfunction as the first argument. `get` allows you to fetch the contextual valueof any atom.
```jsxconst doubledCountAtom = atom((get) => get(countAtom) * 2)
function DoubleCounter() { const [doubledCount] = useAtom(doubledCountAtom) return <h2>{doubledCount}</h2>```
## Recipes
### Creating an atom from atoms
You can combine atoms to create a derived atom.
```jsxconst count1 = atom(1)const count2 = atom(2)const count3 = atom(3)
const sum = atom((get) => get(count1) + get(count2) + get(count3))```
Or if you like fp patterns ...
```jsxconst atoms = [count1, count2, count3, ...otherAtoms]const sum = atom((get) => atoms.map(get).reduce((acc, count) => acc + count))```
### Derived async atoms <img src="https://img.shields.io/badge/-needs_suspense-black" alt="needs suspense" />
You can make the read function an async function.
```jsxconst urlAtom = atom("https://json.host.com")const fetchUrlAtom = atom( async (get) => { const response = await fetch(get(urlAtom)) return await response.json() })
function Status() { // Re-renders the component after urlAtom changed and the async function above concludes const [json] = useAtom(fetchUrlAtom)```
### You can create a writable derived atom
Specify a write function at the second argument. `get` will return the currentvalue of an atom. `set` will update an atom's value.
```jsxconst decrementCountAtom = atom( (get) => get(countAtom), (get, set, _arg) => set(countAtom, get(countAtom) - 1),)
function Counter() { const [count, decrement] = useAtom(decrementCountAtom) return ( <h1> {count} <button onClick={decrement}>Decrease</button>```
### Write only atoms
To make a write-only atom, don't define a read function by passing `null` as thefirst argument.
```jsxconst multiplyCountAtom = atom(null, (get, set, by) => set(countAtom, get(countAtom) * by))
function Controls() { const [, multiply] = useAtom(multiplyCountAtom) return <button onClick={() => multiply(3)}>triple</button>```
### Async actions
Make the write function an async function, and call `set` when you're ready.
```jsxconst fetchCountAtom = atom( (get) => get(countAtom), async (_get, set, url) => { const response = await fetch(url) set(countAtom, (await response.json()).count) })
function Controls() { const [count, compute] = useAtom(fetchCountAtom) return <button onClick={() => compute("http://count.host.com")}>compute</button>```