核心概念:State 与 Actions
在 Zustand 中,状态管理的核心是 Store(存储),它包含了应用的 State(状态)和 Actions(动作)。理解这些核心概念是掌握 Zustand 的关键。
State:应用的数据源
State 是应用的数据容器,它存储了应用的所有状态信息。在 Zustand 中,State 可以是任何 JavaScript 类型,包括对象、数组、字符串、数字等。
// 简单的状态
const useStore = create(() => ({
count: 0,
name: 'Zustand',
isLoading: false,
items: [],
}))
Actions:修改状态的方法
Actions 是修改 State 的函数。在 Zustand 中,Actions 直接定义在 Store 内部,与 State 共存。
const useStore = create((set) => ({
// State
count: 0,
// Actions
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
setName: (name) => set({ name }),
setLoading: (isLoading) => set({ isLoading }),
}))
Store:状态与动作的集合
Store 是 Zustand 的核心,它将 State 和 Actions 组织在一起。创建 Store 使用 create 函数,它接受一个函数作为参数,该函数返回 Store 的初始状态和动作。
Store 创建函数的参数
Store 创建函数接收两个参数:
- set:用于修改状态的函数
- get:用于获取当前状态的函数
const useStore = create((set, get) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
// 使用 get 获取当前状态
incrementTwice: () => {
const currentCount = get().count
set({ count: currentCount + 2 })
},
}))
不可变更新
Zustand 鼓励使用不可变更新模式,这意味着你不应该直接修改状态对象,而是应该创建一个新的状态对象。
错误的做法
// 不要这样做!
const useStore = create((set) => ({
user: { name: 'John', age: 30 },
updateAge: (age) => {
set((state) => {
state.user.age = age // 直接修改状态对象
return state
})
},
}))
正确的做法
// 这样做是正确的
const useStore = create((set) => ({
user: { name: 'John', age: 30 },
updateAge: (age) => {
set((state) => ({
user: {
...state.user, // 复制现有属性
age, // 更新年龄
},
}))
},
}))
在组件中使用 State 和 Actions
在 React 组件中,你可以使用自定义 Hook 来访问 Store 中的 State 和 Actions。
访问单个状态
const count = useStore((state) => state.count)
访问多个状态
const { count, name } = useStore((state) => ({
count: state.count,
name: state.name
}))
访问 Actions
const increment = useStore((state) => state.increment)
const { increment, decrement } = useStore((state) => ({
increment: state.increment,
decrement: state.decrement
}))
完整示例
function Counter() {
const count = useStore((state) => state.count)
const { increment, decrement, reset } = useStore((state) => ({
increment: state.increment,
decrement: state.decrement,
reset: state.reset,
}))
return (
<div>
<h1>Count: {count}</h1>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<button onClick={reset}>Reset</button>
</div>
)
}
高级状态管理
计算属性
你可以在 Store 中定义计算属性,它们基于其他状态计算得出。
const useStore = create((set, get) => ({
todos: [
{ id: 1, text: 'Learn Zustand', completed: true },
{ id: 2, text: 'Build an app', completed: false },
],
// 计算属性:完成的任务数量
completedTodosCount: () => get().todos.filter((todo) => todo.completed).length,
// 计算属性:待完成的任务数量
pendingTodosCount: () => get().todos.filter((todo) => !todo.completed).length,
}))
在组件中使用计算属性
function TodoStats() {
const completedCount = useStore((state) => state.completedTodosCount())
const pendingCount = useStore((state) => state.pendingTodosCount())
return (
<div>
<p>Completed: {completedCount}</p>
<p>Pending: {pendingCount}</p>
</div>
)
}
State 与 Actions 的最佳实践
1. 将相关的状态和动作组织在一起
// 好的做法:将计数器相关的状态和动作组织在一起
const useCounterStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}))
2. 保持 Actions 简洁
// 好的做法:每个 Action 只做一件事
const useUserStore = create((set) => ({
user: null,
isLoading: false,
error: null,
fetchUser: async (id) => {
set({ isLoading: true, error: null })
try {
const response = await fetch(`/api/users/${id}`)
const user = await response.json()
set({ user, isLoading: false })
} catch (error) {
set({ error: error.message, isLoading: false })
}
},
}))
3. 使用选择器避免不必要的重渲染
// 好的做法:只订阅需要的状态
const count = useStore((state) => state.count)
// 不好的做法:订阅整个 Store
const store = useStore()
const count = store.count
总结
State 和 Actions 是 Zustand 的核心概念:
- State 是应用的数据源,存储了应用的所有状态信息
- Actions 是修改 State 的函数,定义在 Store 内部
- Store 将 State 和 Actions 组织在一起,是 Zustand 的核心
- 使用不可变更新模式修改状态
- 使用选择器精确订阅状态,避免不必要的重渲染
理解这些核心概念后,你就可以开始构建更复杂的状态管理逻辑了。在接下来的章节中,我们将学习 性能优化:Selector 与 Shallow,进一步提升你的 Zustand 应用性能。
相关内容
- 异步逻辑与 API 请求 了解如何在 Zustand 中处理异步逻辑与 API 请求,包括基本异步 Actions、状态管理最佳实践、高级异步模式以及与其他库的结合使用。
- 调试神器:Redux DevTools 了解如何在 Zustand 中集成和使用 Redux DevTools 进行状态调试,包括安装配置、基本用法、命名 Action、与其他中间件结合使用、高级功能...
- 快速上手:5分钟快速起步 本指南将在5分钟内带您快速掌握Zustand的基本用法,包括安装Zustand、创建第一个Store、在React组件中使用Store、状态共享以及应用运行等内...
- 为什么选择 Zustand? 了解Zustand的核心优势,包括极简API设计、高性能、极小体积、无缝集成React以及强大的中间件支持,并与Redux、Context API、MobX等其...
- 中间件:Immer 简化状态修改 了解如何使用 Zustand 的 Immer 中间件简化状态修改,包括基本用法、与普通状态更新的对比、嵌套对象修改、与其他中间件结合使用以及性能最佳实践等内容。
- 中间件:Persist 持久化 了解如何使用 Zustand 的 persist 中间件将状态持久化到本地存储,包括基本用法、配置选项、自定义存储引擎、部分持久化、状态迁移以及与其他中间件结合...