Scripts2026年4月14日·1 分钟阅读

Jotai — Primitive and Flexible State Management for React

Jotai is an atomic state library for React. You compose atoms like React useState, and Jotai handles subscription, derivation, and async loading — all without the boilerplate of Redux or the global store of Zustand.

Introduction

Jotai (Japanese for "state") takes inspiration from Recoil but simplifies the API to the bare minimum. Every piece of state is an atom, and components subscribe by calling useAtom. Derived atoms, async atoms, and persistence fall out naturally.

With over 21,000 GitHub stars, Jotai is a favorite in the Poimandres collective alongside Zustand and React Three Fiber. It scales from a single counter to complex apps without changing paradigm.

What Jotai Does

Jotai stores atom values in a React context provider. useAtom(atom) subscribes just that component, so updates are surgical — no selectors, no memoization. Atoms can depend on other atoms (derivation), be async (suspend while loading), or be persisted (via storage utilities).

Architecture Overview

atom(initial)
        |
  [Atom Store]
  (per Provider, or default)
        |
  useAtom(a) -> [value, setter]
        |
  Derived atom: get(other)   auto re-evaluates on deps change
  Async atom:   async get()  suspends until resolved
  Writable atom: (get, set, arg) => { ... }
        |
  Subscribed components re-render only when their atom changes

Self-Hosting & Configuration

import { atom, useAtom, Provider } from "jotai";
import { atomWithStorage } from "jotai/utils";
import { atomFamily } from "jotai/utils";

const tokenAtom = atomWithStorage("auth-token", "");

const userQueryAtom = atom(async (get) => {
  const token = get(tokenAtom);
  const res = await fetch("/me", { headers: { Authorization: `Bearer ${token}` } });
  return res.json();
});

const todoByIdAtom = atomFamily((id: string) =>
  atom(async () => (await fetch(`/todos/${id}`)).json())
);

function Root() {
  return (
    <Provider>   {/* optional; default store used if omitted */}
      <Suspense fallback={<div>Loading...</div>}>
        <App />
      </Suspense>
    </Provider>
  );
}

Key Features

  • Atomic — fine-grained subscriptions, no selectors needed
  • Derived atoms — compute from other atoms, auto-reactive
  • Async atoms — work with Suspense or loadable wrappers
  • atomWithStorage — persist to localStorage/sessionStorage/IndexedDB
  • atomFamily — dynamic atoms keyed by arbitrary values
  • Multiple stores — per-Provider stores for isolation (testing, SSR)
  • Integrations — jotai-tanstack-query, jotai-redux, jotai-xstate
  • Tiny — ~3KB core, no required context boilerplate

Comparison with Similar Tools

Feature Jotai Zustand Redux Toolkit Recoil Valtio
Model Atoms Store Single store Atoms Proxy
Size ~3KB ~3KB ~11KB ~20KB ~3KB
Async Native Manual RTK Query Native Manual
DevTools Via plugin Yes Yes (redux-devtools) Yes Via plugin
Suspense Yes No No Yes No
Best For Granular state Simple global state Large apps / Redux shops Facebook-style atoms (sunset) Mutable feel

FAQ

Q: Jotai vs Zustand — both are Poimandres? A: Zustand is a single store (like Redux but tiny). Jotai is many atoms. Use Zustand for globally shared state with selectors; use Jotai when state is fragmented across features.

Q: Is Jotai a Recoil replacement? A: Yes, and now that Recoil is unmaintained, Jotai is the recommended atomic-state library. Migration is mostly renaming + adjusting async semantics.

Q: Does Jotai work with SSR/Next.js? A: Yes. Use createStore() per request to avoid cross-request leaks. The Next.js + Jotai guide in the docs covers App Router specifics.

Q: How do I debug atom updates? A: Install jotai-devtools for a Redux-DevTools-style UI, or use useAtomsDebugValue() for React DevTools integration.

Sources

讨论

登录后参与讨论。
还没有评论,来写第一条吧。

相关资产