import { create } from 'zustand';
// 定义状态接口
interface CounterState {
count: number;
increment: () => void;
decrement: () => void;
reset: () => void;
}
// 创建zustand store
export const useCounterStore = create<CounterState>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
reset: () => set({ count: 0 }),
}));
// 用户信息状态
interface UserState {
user: {
name: string;
email: string;
} | null;
setUser: (user: { name: string; email: string }) => void;
clearUser: () => void;
}
export const useUserStore = create<UserState>((set) => ({
user: null,
setUser: (user) => set({ user }),
clearUser: () => set({ user: null }),
}));
import React from 'react';
import { useCounterStore } from '../store';
const Counter: React.FC = () => {
const { count, increment, decrement, reset } = useCounterStore();
return (
<div style={{
padding: '20px',
border: '1px solid #ccc',
borderRadius: '8px',
margin: '20px 0',
textAlign: 'center'
}}>
<h2>计数器示例</h2>
<div style={{ fontSize: '2rem', margin: '20px 0', color: '#61dafb' }}>
当前计数: {count}
</div>
<div style={{ display: 'flex', gap: '10px', justifyContent: 'center' }}>
<button
onClick={increment}
style={{
padding: '10px 20px',
fontSize: '16px',
backgroundColor: '#61dafb',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
增加
</button>
<button
onClick={decrement}
style={{
padding: '10px 20px',
fontSize: '16px',
backgroundColor: '#ff6b6b',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
减少
</button>
<button
onClick={reset}
style={{
padding: '10px 20px',
fontSize: '16px',
backgroundColor: '#feca57',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
重置
</button>
</div>
</div>
);
};
export default Counter;
加上immer 他就是在堆上生成新地址,Immer 的核心机制就是通过在堆上创建新的对象来实现不可变性。
传统方式 vs Immer
// 每层都要手动创建新对象
const newState = {
...state, // 新对象 1
user: {
...state.user, // 新对象 2
profile: {
...state.user.profile, // 新对象 3
name: 'New Name'
}
}
};
immer 方式 :
// Immer 自动处理对象创建
const newState = produce(state, draft => {
draft.user.profile.name = 'New Name';
// Immer 内部:
// 1. 检测到 draft.user 被访问 → 创建 user 的副本
// 2. 检测到 draft.user.profile 被访问 → 创建 profile 的副本
// 3. 检测到 draft.user.profile.name 被修改 → 标记为已修改
});
Immer 的优势
- 代码可读性 : 更接近直观的"修改"操作
- 减少错误 : 避免忘记展开操作符或深拷贝
- 性能优化 : Immer 只会更新实际改变的部分
- 类型安全 : 完全支持 TypeScript
- 调试友好 : 更容易理解状态变化
何时使用 Immer
- ✅ 深层嵌套的对象结构
- ✅ 复杂的数组操作
- ✅ 多个字段同时更新
- ✅ 团队协作(降低学习成本)
- ❌ 简单的状态(如单个计数器)
- ❌ 性能极度敏感的场景
- ❌ 状态结构很扁平 总结 : Immer 让复杂状态管理变得像操作普通 JavaScript 对象一样简单,同时保持 React 状态管理的不可变性要求。
persist 是 Zustand 的一个中间件,主要作用就是将状态持久化存储到 localStorage (或其他存储方式)中。
import { persist } from 'zustand/middleware';
const useCounterStore = create(
persist(
(set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}),
{
name: 'counter-storage', // localStorage 的 key 名称
}
)
);