Language: JavaScript
State Management
Jotai was created by Daishi Kato to offer a minimalistic alternative for React state management. Its design emphasizes simplicity, direct usage of React hooks, and a focus on atomic state, where each atom represents an independent piece of state.
Jotai is a primitive and flexible state management library for React. It provides atoms as units of state, allowing fine-grained control over state updates without the boilerplate of larger libraries like Redux.
npm install jotaiyarn add jotaiJotai uses atoms to define pieces of state. Components subscribe to atoms using the `useAtom` hook, automatically re-rendering when the atom’s value changes. Derived atoms allow computed state and asynchronous operations.
import { atom, useAtom } from 'jotai';
const countAtom = atom(0);
function Counter() {
const [count, setCount] = useAtom(countAtom);
return (
<div>
<button onClick={() => setCount(c => c - 1)}>-</button>
<span>{count}</span>
<button onClick={() => setCount(c => c + 1)}>+</button>
</div>
);
}Defines an atom `countAtom` with an initial value of 0 and uses `useAtom` to read and update the state in a component.
import { atom, useAtom } from 'jotai';
const countAtom = atom(0);
const doubleCountAtom = atom(get => get(countAtom) * 2);
function DoubleCounter() {
const [doubleCount] = useAtom(doubleCountAtom);
return <div>Double Count: {doubleCount}</div>;
}Creates a derived atom `doubleCountAtom` that computes its value from another atom.
import { atom, useAtom } from 'jotai';
const asyncDataAtom = atom(async () => {
const res = await fetch('https://api.example.com/data');
return res.json();
});
function AsyncComponent() {
const [data] = useAtom(asyncDataAtom);
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}Demonstrates an asynchronous atom that fetches data from an API and makes it available to components.
import { atom, useAtom } from 'jotai';
const firstNameAtom = atom('John');
const lastNameAtom = atom('Doe');
const fullNameAtom = atom(
get => `${get(firstNameAtom)} ${get(lastNameAtom)}`,
(get, set, newFullName) => {
const [first, last] = newFullName.split(' ');
set(firstNameAtom, first);
set(lastNameAtom, last);
}
);Shows a writable derived atom `fullNameAtom` that updates multiple underlying atoms when set.
Keep atoms small and focused for better performance and reusability.
Use derived atoms for computed state instead of duplicating logic in components.
Handle asynchronous operations with async atoms or separate utility functions.
Avoid unnecessary re-renders by subscribing components only to the atoms they need.
Use `atomWithStorage` for persisting state in localStorage or sessionStorage.