Jotai logo

Jotai

原子化 React 状态管理库——用极简的原子模型替代 useState + useContext 组合,自底向上构建可组合、可代码分割的全局状态。

精选工具状态管理React原子化Hooks

Jotai 是 React 原子化状态管理库,采用自底向上的原子模型。核心 API 极简(仅 5 个导出),支持派生状态图、Suspense、代码分割和 Provider-less 模式,gzip 后仅 4KB。2026 年与 Zustand 并列为 React 状态管理首选方案。

Jotai

原子化 React 状态管理库——用极简的原子模型替代 useState + useContext 组合,自底向上构建可组合、可代码分割的全局状态。


技术简介说明

Jotai(日语"状態"的罗马音)是由 pmndrs 维护的 React 状态管理库,由 Daishi Kato 设计。它采用原子化(Atomic)模型管理全局状态——每个状态片段(atom)是独立的、可组合的原语,组件通过订阅依赖图自动获得最小化重渲染。

与 Zustand 的"单 store 自顶向下"思路相反,Jotai 走的是"多 atom 自底向上"路线:你可以像拼乐高一样,从最基础的 atom 派生出任意复杂的状态图,而无需预先规划全局 store 结构。这使得 Jotai 既适合作为 useState 的简单升级,也能胜任企业级应用的复杂场景。

截至 2026 年 7 月,Jotai 最新版本为 v2.20.1,GitHub 星标超过 21.2k,周下载量约 530 万次,gzip 后仅 4.0 kB,是 React 生态中最轻量的状态管理方案之一。


基本信息

项目信息
官网https://jotai.org
GitHubhttps://github.com/pmndrs/jotai
npmhttps://www.npmjs.com/package/jotai
最新版本v2.20.1(2026-06-11 发布)
LicenseMIT
GitHub Stars~21.2k
周下载量~530 万
Bundle Size核心 ~2 kB / 完整 ~4 kB(gzip)
TypeScript原生支持,源码 84.8% TypeScript
主要维护者Daishi Kato(@dai_shi),同为 Zustand、Valtio、Waku 作者
所属组织pmndrs / jotaijs(GitHub 下有 40+ 个生态仓库)
Node.js 要求>= 18
React 要求>= 18(支持 React 19)

快速上手

安装

# npm
npm install jotai
 
# yarn
yarn add jotai
 
# pnpm
pnpm add jotai
 
# bun
bun add jotai

最小示例

import { atom, useAtom } from 'jotai'
 
// 1. 定义 atom(全局可复用的状态原语)
const countAtom = atom(0)
const doubleAtom = atom((get) => get(countAtom) * 2) // 派生 atom
 
// 2. 在组件中使用
function Counter() {
  const [count, setCount] = useAtom(countAtom)
  const double = useAtomValue(doubleAtom)
 
  return (
    <div>
      <p>Count: {count} (Double: {double})</p>
      <button onClick={() => setCount((c) => c + 1)}>+1</button>
    </div>
  )
}

完整应用配置

import { atom, useAtom, useAtomValue, useSetAtom, Provider } from 'jotai'
import { atomWithStorage } from 'jotai/utils'
 
// 基础 atom
const nameAtom = atom('World')
 
// 派生 atom(只读)
const greetingAtom = atom((get) => `Hello, ${get(nameAtom)}!`)
 
// 可写派生 atom
const themeAtom = atom<'light' | 'dark'>('light')
 
// 持久化 atom(自动同步 localStorage)
const settingsAtom = atomWithStorage('settings', {
  fontSize: 14,
  language: 'zh-CN',
})
 
// Provider 包裹(可选,不包裹时使用默认 store)
function App() {
  return (
    <Provider>
      <Counter />
      <Settings />
    </Provider>
  )
}
 
// 分别使用只读和只写 hook,优化组件粒度
function Settings() {
  const greeting = useAtomValue(greetingAtom) // 只读
  const setTheme = useSetAtom(themeAtom)       // 只写
 
  return (
    <div>
      <p>{greeting}</p>
      <button onClick={() => setTheme('dark')}>暗色模式</button>
    </div>
  )
}

核心概念与架构

原子模型(Atomic Model)

Jotai 的灵感来源于 React 的 useState,但将状态提升到了全局可共享的维度:

  • atom 是状态的唯一原语,每个 atom 持有独立的状态值
  • 组件通过 useAtom 订阅 atom,Jotai 根据依赖图精确判断哪些组件需要重渲染
  • atom 之间可以形成派生关系(derived atoms),自动追踪依赖并级联更新
atom 依赖图示意:

  countAtom ──→ doubleAtom ──→ Display 组件
       │
       └──→ tripleAtom ────→ Other 组件

四层架构

层级包名说明
Corejotai最小核心:atomuseAtomuseAtomValueuseSetAtomProvidercreateStore
Utilitiesjotai/utils实用工具:持久化、SSR hydration、跨 tab 同步、加载状态等
Extensionsjotai-effectjotai-immer官方维护的第三方库集成
ToolsSWC / Babel 插件编译器支持:React Fast Refresh、调试标签

三种 Atom 类型

// 1. 基础 atom(可读写)
const countAtom = atom(0)
 
// 2. 只读派生 atom
const doubleAtom = atom((get) => get(countAtom) * 2)
 
// 3. 可写派生 atom(自定义读写逻辑)
const doubledCountAtom = atom(
  (get) => get(countAtom) * 2,           // read
  (get, set, newValue: number) => {       // write
    set(countAtom, newValue / 2)
  }
)
 
// 4. 异步 atom(支持 React Suspense)
const fetchAtom = atom(async (get) => {
  const res = await fetch(`/api/data/${get(idAtom)}`)
  return res.json()
})

Store 与 Provider

import { createStore } from 'jotai'
 
// 创建独立 store(支持多实例隔离)
const store = createStore()
 
// 在 React 树外读写
store.set(countAtom, 42)
const value = store.get(countAtom) // 42
 
// 在 React 组件树中注入
<Provider store={store}>
  <App />
</Provider>

核心特性

1. 极简核心 API

核心仅暴露 atomuseAtomuseAtomValueuseSetAtomProvider 五个导出,学习曲线极低,从 useState 迁移几乎零成本。

2. 最小化重渲染(No Unnecessary Re-renders)

基于原子依赖图的精确订阅机制,组件只在依赖的 atom 值变化时重渲染,无需 useMemouseCallbackReact.memo 手动优化。

3. 派生状态图(Derived Atoms)

atom 可从其他 atom 派生,形成有向无环图(DAG),依赖追踪自动完成。派生 atom 可以是只读的,也可以自定义写入逻辑。

4. React Suspense 原生支持

异步 atom 可直接配合 &lt;Suspense&gt; 使用,Jotai 管理 Promise 的生命周期,支持 loadingerror 状态的优雅处理。

5. Provider-less 模式

不提供 &lt;Provider&gt; 时,Jotai 自动使用内部默认 store,减少样板代码。需要多 store 隔离时再显式使用 Provider。

6. 完整的 TypeScript 支持

从核心 API 到工具函数,全部提供精确的类型推导,包括泛型 atom、可写类型推导、异步 atom 类型等。

7. 代码分割友好

每个 atom 是独立的模块,可随组件自动代码分割,无需像单 store 方案那样将全部状态打入主 bundle。

8. Store 外部访问

createStore() 允许在非 React 环境(如 Node.js、测试、定时器、Web Worker)中读写状态。

9. 丰富的工具生态

内置 atomWithStorage(localStorage/sessionStorage 持久化)、atomFamily(参数化 atom 工厂)、atomWithReducerselectAtom 等 20+ 工具函数。

10. 官方扩展与集成

官方维护 jotai-immer(Immer 可变更新)、jotai-optics(focusAtom 聚焦派生)、jotai-effect(副作用管理)、jotai-tanstack-query(与 TanStack Query 集成)等。


生态图

Jotai 生态全景
│
├── 核心(jotai)
│   ├── atom / useAtom / useAtomValue / useSetAtom
│   ├── Provider / createStore
│   └── jotai/utils
│       ├── atomWithStorage      ── localStorage / sessionStorage 持久化
│       ├── atomFamily           ── 参数化 atom 工厂
│       ├── atomWithReducer      ── reducer 模式 atom
│       ├── selectAtom           ── 选择性订阅
│       ├── loadable             ── 异步 atom 加载状态(v2.x 已废弃)
│       ├── waitForAll           ── 并行等待多个 atom
│       └── hydrateAtom          ── SSR hydration 支持
│
├── 官方扩展(Extensions)
│   ├── jotai-effect             ── 全局副作用 / store 级别响应
│   ├── jotai-immer              ── Immer 风格不可变更新
│   ├── jotai-optics             ── focusAtom 结构聚焦
│   ├── jotai-tanstack-query     ── TanStack Query 集成
│   ├── jotai-xstate             ── XState 状态机集成
│   └── jotai-location           ── URL 状态同步
│
├── 工具链(Tools)
│   ├── jotai-swc-plugin         ── SWC 编译器插件(Fast Refresh)
│   └── jotai-babel-plugin       ── Babel 插件(调试标签)
│
├── 社区集成
│   ├── jotai-trpc               ── tRPC 集成
│   ├── jotai-form               ── 表单管理
│   ├── jotai-suspensive         ── Suspense 增强(@toss/suspensive)
│   └── jotai-devtools           ── 浏览器开发者工具
│
└── 平台适配
    ├── React(Web)
    ├── React Native
    ├── Next.js / App Router
    ├── Remix
    └── Waku

适用场景

1. useState + useContext 的性能升级

当 Prop Drilling 严重或 Context 导致不必要的全局重渲染时,Jotai 是最直接的替代方案——原子粒度订阅彻底消除 Context 的性能陷阱。

2. 需要代码分割的中大型应用

Jotai 的 atom 天然支持按模块拆分,配合动态 import() 实现状态随路由懒加载,适合代码分割需求强烈的 Next.js / Remix 项目。

3. 异步数据流与 Suspense

Jotai 的异步 atom 原生支持 React Suspense,适合需要优雅的 loading/error 状态管理的场景,如数据仪表板、内容管理系统。

4. 复杂的派生状态计算

派生 atom 形成 DAG,自动追踪依赖并缓存计算结果,适合表单联动、筛选/排序/分页组合、复杂业务规则等场景。

5. 跨组件共享的轻量状态

如主题切换、用户偏好、购物车、通知计数等——不需要 Redux 的繁重仪式,又不想引入 Context 的性能开销。

6. 需要在 React 树外管理状态

通过 createStore(),可在 Web Worker、定时器、WebSocket 回调、Node.js 脚本中直接读写状态,适合实时通信和后台任务。

7. Recoil 迁移

Meta 已停止维护 Recoil,Jotai 被社区视为事实上的替代方案——API 相近但更轻量,无字符串 key,支持 Provider-less 模式。


开发与工程化

TypeScript 配置

// Jotai 对 TypeScript 有完整的原生支持
import { atom, useAtom } from 'jotai'
 
// 类型自动推导
const countAtom = atom(0)           // Atom<number>
const nameAtom = atom<string>('')   // Atom<string>
 
// 派生 atom 类型推导
const doubleAtom = atom((get) => get(countAtom) * 2) // Atom<number>
 
// 异步 atom 类型推导
const fetchAtom = atom(async (get) => {
  // 返回类型自动推导
  const res = await fetch('/api/data')
  return res.json() as Promise<{ id: number; name: string }>
})

SSR / Next.js 集成

// app/layout.tsx(Next.js App Router)
import { Provider } from 'jotai'
import { createStore } from 'jotai'
 
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        <Provider>
          {children}
        </Provider>
      </body>
    </html>
  )
}
 
// 使用 atomWithStorage 实现 SSR 安全的持久化
import { atomWithStorage, createJSONStorage } from 'jotai/utils'
 
const safeStorage = createJSONStorage(() => sessionStorage)
const themeAtom = atomWithStorage('theme', 'light', undefined, {
  getOnInit: true, // SSR 时从 storage 初始化
})

测试

import { createStore } from 'jotai'
import { countAtom, doubleAtom } from './atoms'
 
test('count atom updates correctly', () => {
  const store = createStore()
  expect(store.get(countAtom)).toBe(0)
 
  store.set(countAtom, 5)
  expect(store.get(countAtom)).toBe(5)
  expect(store.get(doubleAtom)).toBe(10)
})

调试与 DevTools

// 安装 jotai-devtools
import { useAtomDevtools } from 'jotai/devtools'
 
function AtomDebugger() {
  useAtomDevtools(countAtom, 'Counter')
  return null
}
 
// SWC 插件:自动添加调试标签
// .swcrc 中配置 jotai-swc-plugin

性能与安全

性能特征

指标数据
核心 bundle(gzip)~2 kB
完整包(gzip)~4 kB
单状态更新延迟~14ms(2026 基准测试)
重渲染精度依赖图精确订阅,零多余渲染
内存占用每个 atom 仅持有当前值与订阅者列表

性能优化要点

  • 使用 useAtomValue + useSetAtom 拆分读写,避免不必要的订阅
  • 派生 atom 自动缓存,避免重复计算
  • selectAtom 可在单个 atom 内精确订阅子字段
  • Provider-less 模式省去 Provider 层开销

安全考量

  • XSS:Jotai 本身不处理 HTML,但持久化到 localStorage 的 atom 需警惕存储型 XSS——不要存储未清洗的用户输入
  • 状态注入atomWithStoragegetOnInit 会在 SSR 时读取 storage,确保数据来自可信源
  • 依赖:Jotai 核心零依赖(no dependencies),供应链风险极低
  • CSP:Jotai 不使用 eval 或动态代码生成,兼容严格 CSP 策略

技术对比

特性JotaiZustandRedux ToolkitRecoilValtio
模型原子化(多 atom)单 store单 store + slice原子化(多 atom)代理(Proxy)
Bundle(gzip)~4 kB~1.1 kB~11 kB~14 kB~3.5 kB
学习曲线
TypeScript原生优秀原生优秀原生优秀良好原生优秀
代码分割天然支持需配置需配置部分支持需配置
Suspense 支持原生需配合需配合原生需配合
DevToolsRedux DevTools / jotai-devtoolsRedux DevToolsRedux DevTools官方 DevTools自带 Proxy 调试
Provider 必需否(可 Provider-less)
派生状态派生 atom(DAG)selectorcreateSlice + selectorselectorFamilyProxy 自动追踪
持久化atomWithStorage 内置persist middlewareredux-persist需自建需自建
维护状态活跃(2026 持续更新)活跃(2026 持续更新)活跃已停止维护活跃
适合场景原子粒度、代码分割、Suspense轻量全局状态、快速上手大型团队、复杂领域逻辑已不推荐新项目使用偏好可变更新风格

Jotai vs Zustand 核心差异

// Zustand:单 store,模块通过 selector 切片
const useStore = create((set) => ({
  count: 0,
  name: '',
  increment: () => set((s) => ({ count: s.count + 1 })),
}))
 
// Jotai:多 atom,独立定义,自由组合
const countAtom = atom(0)
const nameAtom = atom('')
const incrementAtom = atom(null, (get, set) => {
  set(countAtom, get(countAtom) + 1)
})
  • Zustand 更适合"一个全局状态对象"的心智模型,API 接近简化版 Redux
  • Jotai 更适合"状态由多个独立原语组合"的心智模型,天然支持代码分割和粒度优化
  • 两者均由 Daishi Kato 主导设计,哲学不同但互为补充

最佳实践

1. 用 useAtomValue + useSetAtom 替代 useAtom

// ✅ 推荐:读写分离,精确订阅
const count = useAtomValue(countAtom)
const setCount = useSetAtom(countAtom)
 
// ❌ 避免:不需要读写时仍使用 useAtom
const [count, setCount] = useAtom(countAtom)

2. 派生 atom 优先于组件内计算

// ✅ 推荐:派生 atom 自动缓存,多组件共享
const totalAtom = atom((get) =>
  get(itemsAtom).reduce((sum, item) => sum + item.price, 0)
)
 
// ❌ 避免:每个组件重复计算
function Total() {
  const items = useAtomValue(itemsAtom)
  const total = items.reduce((sum, item) => sum + item.price, 0)
  // 每个订阅 items 的组件都重算
}

3. 使用 atomFamily 管理参数化 atom

import { atomFamily } from 'jotai/utils'
 
// ✅ 缓存相同参数的 atom 实例
const userAtom = atomFamily((id: string) =>
  atom(async () => {
    const res = await fetch(`/api/users/${id}`)
    return res.json()
  })
)
 
function UserProfile({ id }: { id: string }) {
  const user = useAtomValue(userAtom(id))
  return <div>{user.name}</div>
}

4. 谨慎使用 atomWithStorage

// ✅ 设置合理的初始值和存储策略
const settingsAtom = atomWithStorage(
  'app-settings',
  { theme: 'light', lang: 'zh-CN' },
  undefined,
  { getOnInit: true }
)
 
// ⚠️ 避免存储大量数据或敏感信息
// localStorage 有 5MB 限制,且可被 XSS 读取

5. 多 store 隔离复杂子系统

// ✅ 不同子系统使用独立 store,避免状态耦合
const editorStore = createStore()
const viewerStore = createStore()
 
function EditorPanel() {
  return (
    <Provider store={editorStore}>
      <RichTextEditor />
    </Provider>
  )
}

技术局限与边界

已知局限

  1. 无内置时间旅行调试 不像 Redux 有完整的 Action 历史和时间旅行,Jotai 的 atom 更新是分散的,调试需要依赖 DevTools 扩展或手动日志。

  2. 大规模平坦状态需手动组织 当 atom 数量达到数百个时,需要自行规划命名和模块划分——Jotai 不提供 Redux 那样的 slice 或 domain 约定。

  3. 派生 DAG 的深度需谨慎 过深的派生链(>5 层)可能导致级联更新难以追踪,建议扁平化设计或使用 selectAtom 截断依赖。

  4. 与 React 版本强耦合 Jotai 深度依赖 React 的 Concurrent Mode 和 Suspense 机制,非 React 框架(Vue、Svelte)无法使用。

  5. 生态规模仍小于 Redux 虽然核心 + 官方扩展已足够丰富,但社区中间件、教程、第三方集成的总量仍远不及 Redux 生态。

  6. Proxy 风格更新不支持 不像 Valtio 可以直接 state.count++,Jotai 始终需要通过 set 函数更新,对偏好可变风格的用户不够直觉。

不适用场景

  • 纯服务端状态管理——TanStack Query 更合适
  • 复杂有限状态机——XState 更合适
  • 跨框架共享状态——需要框架无关方案(如 Signals 或自研)
  • 极简单页面——useState 足矣,引入 Jotai 反而增加复杂度

学习资源

官方资源

深入理解

社区与教程


2026 年现状

版本状态

截至 2026 年 7 月,Jotai 处于 v2.20.1 稳定版本,v3 尚未发布但已进入规划阶段

  • v2.20.0(2026-05)引入了 Store Building Blocks——暴露内部 API 供生态库扩展,Daishi 称其为"构建 Jotai v3 的基础"
  • v2.x 最新变更中,loadable 工具已标记为废弃,为 v3 清理做准备

v3 规划方向

根据 GitHub Discussion #2889,v3 计划包括:

  • 放弃旧版 TypeScript 支持(要求 TS 5.x+)
  • 放弃 UMD / SystemJS 构建
  • 放弃旧版 Node.js(要求 Node 20+)
  • package.json 改为模块优先(ESM-only)
  • 放弃 CommonJS 构建
  • 使用 process.env 替代构建时常量

生态趋势

  • Recoil 退役后的首选替代:Meta 已于 2024 年停止 Recoil 维护,2025–2026 年社区大规模迁移至 Jotai,Jotai 被多篇 2026 年文章称为"原子状态管理的活跃继承者"
  • 与 Zustand 并列为双雄:2026 年多篇对比文章将 Zustand 和 Jotai 并列为 React 状态管理的两大首选,Redux Toolkit 退居企业级遗留项目
  • pmndrs 持续投入:Jotai 与 Zustand、Valtio 同属 pmndrs 生态,共享维护资源,GitHub 组织下有 40+ 个集成仓库
  • React Paris 2026 关注:Daishi Kato 在 React Paris 2026(3 月)发表主题演讲,分享三大库的设计哲学,显示社区持续活跃
  • 开源健康度优秀:Jotai 与 Zustand 的 open issues 分别仅 3 个和 4 个,表明代码库稳定、维护响应迅速

总结

Jotai 在 2026 年已从一个" Recoil 的轻量替代品"成长为 React 状态管理的主流方案之一。它凭借极简 API、原子化设计、出色的 TypeScript 体验和零依赖核心,在"现代 React 状态管理"话题中与 Zustand 并列首选。随着 Recoil 退出历史舞台和 v3 的筹备,Jotai 正处于生态扩张与技术演进的关键节点。