核心概念:State 与 Actions
在 Zustand 中,状态管理的核心是 Store(存储),它包含了应用的 State(状态)和 Actions(动作)。理解这些核心概念是掌握 Zustand 的关键。
State:应用的数据源
State 是应用的数据容器,它存储了应用的所有状态信息。在 Zustand 中,State 可以是任何 JavaScript 类型,包括对象、数组、字符串、数字等。
javascript
// 简单的状态
const useStore = create(() => ({
count: 0,
name: 'Zustand',
isLoading: false,
items: [],
}))Actions:修改状态的方法
Actions 是修改 State 的函数。在 Zustand 中,Actions 直接定义在 Store 内部,与 State 共存。
javascript
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:用于获取当前状态的函数
javascript
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 鼓励使用不可变更新模式,这意味着你不应该直接修改状态对象,而是应该创建一个新的状态对象。
错误的做法
javascript
// 不要这样做!
const useStore = create((set) => ({
user: { name: 'John', age: 30 },
updateAge: (age) => {
set((state) => {
state.user.age = age // 直接修改状态对象
return state
})
},
}))正确的做法
javascript
// 这样做是正确的
const useStore = create((set) => ({
user: { name: 'John', age: 30 },
updateAge: (age) => {
set((state) => ({
user: {
...state.user, // 复制现有属性
age, // 更新年龄
},
}))
},
}))在组件中使用 State 和 Actions
在 React 组件中,你可以使用自定义 Hook 来访问 Store 中的 State 和 Actions。
访问单个状态
jsx
const count = useStore((state) => state.count)访问多个状态
jsx
const { count, name } = useStore((state) => ({
count: state.count,
name: state.name
}))访问 Actions
jsx
const increment = useStore((state) => state.increment)
const { increment, decrement } = useStore((state) => ({
increment: state.increment,
decrement: state.decrement
}))完整示例
jsx
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 中定义计算属性,它们基于其他状态计算得出。
javascript
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,
}))在组件中使用计算属性
jsx
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. 将相关的状态和动作组织在一起
javascript
// 好的做法:将计数器相关的状态和动作组织在一起
const useCounterStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}))2. 保持 Actions 简洁
javascript
// 好的做法:每个 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. 使用选择器避免不必要的重渲染
jsx
// 好的做法:只订阅需要的状态
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 应用性能。