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. 性能优化 :使用 useAtomValueuseSetAtom 分离读写
  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 应用的理想状态管理解决方案,特别是当你需要细粒度状态控制而不想处理复杂样板代码时。

相关推荐
小小小小宇23 分钟前
前端小tips
前端
小小小小宇32 分钟前
二维数组按顺时针螺旋顺序
前端
安木夕1 小时前
C#-Visual Studio宇宙第一IDE使用实践
前端·c#·.net
努力敲代码呀~1 小时前
前端高频面试题2:浏览器/计算机网络
前端·计算机网络·html
高山我梦口香糖1 小时前
[electron]预脚本不显示内联script
前端·javascript·electron
神探小白牙1 小时前
vue-video-player视频保活成功确无法推送问题
前端·vue.js·音视频
Angel_girl3192 小时前
vue项目使用svg图标
前端·vue.js
難釋懷2 小时前
vue 项目中常用的 2 个 Ajax 库
前端·vue.js·ajax
Qian Xiaoo2 小时前
Ajax入门
前端·ajax·okhttp
爱生活的苏苏3 小时前
vue生成二维码图片+文字说明
前端·vue.js