🌙 React 状态管理之 Jotai 入门和最佳实践
Jotai 是一个轻量级的状态管理库,专为 React 应用设计。它提供了简单且高效的状态管理解决方案,易于上手且功能强大。以下是 Jotai 的入门指南和实践示例。
🌙 1. 安装 Jotai
首先,你需要安装 Jotai:
npm install jotai
1
🌙 2. 核心概念和 API
Jotai 的核心是 atom 和 React hooks。以下是 Jotai 的主要 API 和用法:
🌙 2.1 atom
atom 是 Jotai 的基本单位,用于存储状态。
import { atom } from 'jotai';
export const countAtom = atom(0); // 创建一个 atom
1
2
3
2
3
🌙 2.2 useAtom
useAtom 是最常用的 hook,用于读取和写入 atom 的值。
import { useAtom } from 'jotai';
import { countAtom } from '../store/atoms';
const Counter = () => {
const [count, setCount] = useAtom(countAtom);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
</div>
);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
🌙 2.3 useAtomValue
useAtomValue 用于只读取 atom 的值,适合不需要更新状态的场景。
import { useAtomValue } from 'jotai';
import { countAtom } from '../store/atoms';
const DisplayCount = () => {
const count = useAtomValue(countAtom);
return <h1>Count: {count}</h1>;
};
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
🌙 2.4 useSetAtom
useSetAtom 用于只更新 atom 的值,适合不需要读取状态的场景。
import { useSetAtom } from 'jotai';
import { countAtom } from '../store/atoms';
const IncrementButton = () => {
const setCount = useSetAtom(countAtom);
return <button onClick={() => setCount((prev) => prev + 1)}>Increment</button>;
};
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
🌙 2.5 atomWithDefault
atomWithDefault 用于创建带有默认值的 atom,默认值可以是动态计算的。
import { atom, atomWithDefault } from 'jotai';
const baseCountAtom = atom(0);
export const doubleCountAtom = atomWithDefault((get) => get(baseCountAtom) * 2);
1
2
3
4
2
3
4
🌙 2.6 loadable
loadable 用于处理异步状态,支持加载中和错误状态。
import { atom, loadable } from 'jotai';
const asyncDataAtom = atom(async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
return response.json();
});
export const loadableDataAtom = loadable(asyncDataAtom);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
🌙 2.7 atomWithStorage
atomWithStorage 用于将状态持久化到 localStorage 或 sessionStorage。
import { atomWithStorage } from 'jotai/utils';
export const themeAtom = atomWithStorage('theme', 'light');
1
2
3
2
3
🌙 3. 在 Next.js 中使用 Jotai
Jotai 可以无缝集成到 Next.js 中。以下是一个示例:
🌙 3.1 创建 Atom
// src/store/atoms.ts
import { atom } from 'jotai';
export const countAtom = atom(0);
1
2
3
4
2
3
4
🌙 3.2 使用 Atom
// src/pages/index.tsx
import { useAtom } from 'jotai';
import { countAtom } from '../store/atoms';
const Home = () => {
const [count, setCount] = useAtom(countAtom);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
</div>
);
};
export default Home;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
🌙 3.3 服务端渲染
Jotai 支持服务端渲染(SSR)。你可以在 getServerSideProps 或 getStaticProps 中初始化状态。
// src/pages/index.tsx
import { useAtom } from 'jotai';
import { countAtom } from '../store/atoms';
export const getServerSideProps = async () => {
return {
props: {
initialCount: 10,
},
};
};
const Home = ({ initialCount }: { initialCount: number }) => {
const [count, setCount] = useAtom(countAtom);
// 初始化状态
React.useEffect(() => {
setCount(initialCount);
}, [initialCount, setCount]);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
</div>
);
};
export default Home;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
🌙 4. 高级用法
🌙 4.1 组合 Atom
通过组合 atom,可以创建复杂的状态逻辑。
import { atom } from 'jotai';
const countAtom = atom(0);
export const doubleCountAtom = atom((get) => get(countAtom) * 2);
1
2
3
4
2
3
4
🌙 4.2 异步状态管理
Jotai 支持异步状态管理,适合数据加载场景。
import { atom } from 'jotai';
export const asyncDataAtom = atom(async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
return response.json();
});
1
2
3
4
5
6
2
3
4
5
6
🌙 4.3 中间件
使用 atomWithStorage 或自定义逻辑实现状态持久化。
import { atomWithStorage } from 'jotai/utils';
export const userPreferencesAtom = atomWithStorage('preferences', { theme: 'light' });
1
2
3
2
3
🌙 5. 最佳实践
- 使用
useAtomValue和useSetAtom:根据需求选择合适的 hook,避免不必要的重新渲染。 - 状态持久化:使用
atomWithStorage持久化重要状态。 - 异步操作:使用
loadable处理异步状态。 - 类型安全:在 TypeScript 中定义 atom 的类型。
- 模块化:将 atom 和组件分离,保持代码清晰。
🌙 6. 示例项目结构
以下是一个推荐的项目结构:
my-project/
├── src/
│ ├── store/
│ │ └── atoms.ts
│ ├── components/
│ │ ├── Counter.tsx
│ │ ├── AsyncData.tsx
│ │ └── DoubleCounter.tsx
│ ├── pages/
│ │ └── index.tsx
├── package.json
└── tsconfig.json
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
🌙 7. 总结
Jotai 是一个功能强大且易于使用的状态管理库。通过掌握其核心 API 和最佳实践,你可以轻松管理 React 和 Next.js 应用中的状态。