Jotai 使用详解:React 轻量级状态管理库

Jotai 是一个 React 全局状态管理库,以其原子化模型和简洁 API 著称。它类似于 Recoil,但更加轻量且易于使用。下面我将详细介绍 Jotai 的核心概念和使用方法。

Jotai 官方文档

1. 基础用法

创建原子 (Atom)

原子是 Jotai 中的基本状态单元:

js 复制代码
import { atom } from 'jotai';

// 创建一个原子
const countAtom = atom(0); // 初始值为0

使用原子

在组件中使用 useAtom hook:

js 复制代码
import { useAtom } from 'jotai';

function Counter() {
  const [count, setCount] = useAtom(countAtom);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

2. 派生原子

Jotai 允许创建基于其他原子的派生状态:

js 复制代码
const doubleCountAtom = atom((get) => get(countAtom) * 2);

function DisplayDouble() {
  const [doubleCount] = useAtom(doubleCountAtom);
  return <p>Double count: {doubleCount}</p>;
}

3. 异步原子

Jotai 支持异步操作:

js 复制代码
const fetchUserAtom = atom(async () => {
  const response = await fetch('https://api.example.com/user');
  return response.json();
});

function UserProfile() {
  const [user] = useAtom(fetchUserAtom);
  
  if (!user) return <div>Loading...</div>;
  
  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  );
}

4. 写入派生原子

可以创建既可读又可写的派生原子:

js 复制代码
const countAtom = atom(0);
const incrementCountAtom = atom(
  (get) => get(countAtom),
  (get, set, _arg) => {
    set(countAtom, get(countAtom) + 1);
  }
);

function Counter() {
  const [count, increment] = useAtom(incrementCountAtom);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

5. 实用功能

原子组合

js 复制代码
const firstNameAtom = atom('John');
const lastNameAtom = atom('Doe');

const fullNameAtom = atom((get) => {
  return `${get(firstNameAtom)} ${get(lastNameAtom)}`;
});

本地存储持久化

js 复制代码
import { atomWithStorage } from 'jotai/utils';

const themeAtom = atomWithStorage('theme', 'light');

function ThemeToggle() {
  const [theme, setTheme] = useAtom(themeAtom);
  
  return (
    <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
      Toggle Theme (Current: {theme})
    </button>
  );
}

6. Provider 使用

虽然 Jotai 有默认的全局 store,但也可以创建隔离的 context:

js 复制代码
import { Provider } from 'jotai';

function App() {
  return (
    <Provider>
      <Counter />
      <DisplayDouble />
    </Provider>
  );
}

7. 最佳实践

  1. 原子粒度:保持原子小而专注
  2. 派生状态:使用派生原子而不是在组件中计算
  3. 性能优化 :使用 useAtomValue 和 useSetAtom 分离读写
  4. 类型安全:Jotai 完全支持 TypeScript

8. 与其它库比较

特性 Jotai Recoil Zustand Redux
学习曲线 低 中 中 高
包大小 很小(~3KB) 小(~14KB) 小(~5KB) 中(~16KB)
原子模型 ✔️ ✔️ ❌ ❌
异步支持 ✔️ ✔️ ✔️ 需要中间件
Context 可选 需要 不需要 不需要

9. 实际应用示例

js 复制代码
// atoms.js
export const todosAtom = atom([]);
export const filterAtom = atom('all');

export const filteredTodosAtom = atom((get) => {
  const todos = get(todosAtom);
  const filter = get(filterAtom);
  
  return filter === 'all' 
    ? todos 
    : todos.filter(todo => filter === 'completed' ? todo.completed : !todo.completed);
});

// TodoList.jsx
function TodoList() {
  const [todos] = useAtom(filteredTodosAtom);
  const [, setTodos] = useAtom(todosAtom);
  
  const addTodo = (text) => {
    setTodos(prev => [...prev, { text, completed: false }]);
  };
  
  // ...渲染逻辑
}

Jotai 的简洁性和灵活性使其成为中小型 React 应用的理想状态管理解决方案,特别是当你需要细粒度状态控制而不想处理复杂样板代码时。

相关推荐
itmigrate5 小时前
前端项目里,Object.is 并不是 === 的平替
前端
小大宇6 小时前
Vue知识点6-computed计算属性
前端·javascript·vue.js
程序员海军7 小时前
尤雨溪 : Vue 4 已经在规划中了!
前端·javascript·vue.js
2601_949970697 小时前
HumanizeDuration 跨端三方库仓颉适配全流程
前端·javascript·flutter
风骏时光牛马9 小时前
后端服务接口开发与性能优化
前端
kyriewen9 小时前
我让 4 个 AI 互相 review 代码,最温柔的那个下手最狠
前端·程序员·ai编程
计算机魔术师9 小时前
493家公司白砸AI钱?Apollo这组数据戳破了幻觉
前端
IT_陈寒9 小时前
Java静态变量初始化坑得我头皮发麻
前端·人工智能·后端
柳杉10 小时前
用 Codex 完成智慧高速 3D 可视化大屏,从 18 张行业设计稿到可交互的运行监测中心
前端·ai编程·数据可视化
review4454310 小时前
拿到 codex 第一步
前端·agent·vibecoding