07. Zustand 中间件与最佳实践一、5W1H 概述维度内容What使用 persist、devtools 等中间件扩展 ZustandWhy实现状态持久化、调试支持When需要本地存储、Redux DevTools 调试时Wherestore 创建时包裹中间件Who需要高级功能的开发者Howcreate(persist(..., { name: storage }))二、What - 什么是中间件中间件是 Zustand 提供的扩展功能可以增强 store 的能力。常用中间件中间件用途persist状态持久化到 localStorage/sessionStoragedevtoolsRedux DevTools 调试支持immer简化不可变更新subscribeWithSelector支持选择器订阅combine合并多个 store三、Why - 为什么需要中间件3.1 持久化刷新页面后保持状态用户登录、主题设置等。3.2 调试使用 Redux DevTools 查看状态变化、时间旅行调试。3.3 简化代码Immer 中间件简化嵌套状态更新。四、When - 何时使用场景推荐中间件需要本地存储persist需要调试devtools复杂嵌套更新immer生产环境组合使用五、Where - 在哪里使用import { create } from zustand; import { persist, devtools } from zustand/middleware; const useStore create( devtools( persist( (set) ({ // store 定义 }), { name: storage-key } ) ) );六、Who - 谁需要使用需要持久化存储或调试支持的开发者。七、How - 如何使用中间件7.1 persist 中间件import { create } from zustand; import { persist } from zustand/middleware; const useStore create( persist( (set) ({ count: 0, user: null, theme: light, increment: () set((state) ({ count: state.count 1 })), setUser: (user) set({ user }), setTheme: (theme) set({ theme }) }), { name: app-storage, // localStorage key getStorage: () localStorage, // 默认 localStorage } ) );7.2 部分持久化const useStore create( persist( (set) ({ count: 0, temp: 不持久化, user: null, increment: () set((state) ({ count: state.count 1 })), setTemp: (temp) set({ temp }) }), { name: app-storage, // 只持久化 count 和 user partialize: (state) ({ count: state.count, user: state.user }) } ) );7.3 使用 sessionStorageconst useStore create( persist( (set) ({ sessionData: null, setSessionData: (data) set({ sessionData: data }) }), { name: session-storage, getStorage: () sessionStorage, } ) );7.4 自定义存储const useStore create( persist( (set) ({ ... }), { name: custom-storage, getStorage: () ({ getItem: (key) { const value localStorage.getItem(key); console.log(读取:, key, value); return value; }, setItem: (key, value) { console.log(保存:, key, value); localStorage.setItem(key, value); }, removeItem: (key) { console.log(删除:, key); localStorage.removeItem(key); }, }), } ) );7.5 版本控制const useStore create( persist( (set) ({ version: 2, data: { oldField: value, newField: } }), { name: app-storage, version: 2, migrate: (persistedState, version) { if (version 1) { // 迁移逻辑 return { ...persistedState, newField: persistedState.oldField || }; } return persistedState; }, } ) );7.6 devtools 中间件import { devtools } from zustand/middleware; const useStore create( devtools( (set) ({ count: 0, increment: () set((state) ({ count: state.count 1 }), false, increment), decrement: () set((state) ({ count: state.count - 1 }), false, decrement), reset: () set({ count: 0 }, false, reset) }), { name: CounterStore } ) );7.7 immer 中间件npminstallimmerimport { create } from zustand; import { immer } from zustand/middleware/immer; const useStore create( immer((set) ({ user: { profile: { name: 张三, age: 25 }, settings: { theme: light, notifications: true } }, todos: [], // 直接修改immer 处理不可变性 updateProfileName: (name) set((state) { state.user.profile.name name; }), updateSettings: (settings) set((state) { Object.assign(state.user.settings, settings); }), addTodo: (text) set((state) { state.todos.push({ id: Date.now(), text, completed: false }); }), toggleTodo: (id) set((state) { const todo state.todos.find(t t.id id); if (todo) todo.completed !todo.completed; }) })) );7.8 组合多个中间件import { create } from zustand; import { persist, devtools, immer } from zustand/middleware; const useStore create( devtools( persist( immer((set) ({ user: null, token: null, theme: light, login: async (email, password) set((state) { // 使用 immer 直接修改 state.loading true; }), setTheme: (theme) set((state) { state.theme theme; }), logout: () set((state) { state.user null; state.token null; }) })), { name: auth-storage } ), { name: AuthStore } ) );八、最佳实践8.1 Store 拆分// stores/userStore.js export const useUserStore create((set) ({ user: null, setUser: (user) set({ user }) })); // stores/cartStore.js export const useCartStore create((set) ({ items: [], addItem: (item) set((state) ({ items: [...state.items, item] })) })); // stores/themeStore.js export const useThemeStore create( persist( (set) ({ theme: light, toggleTheme: () set((state) ({ theme: state.theme light ? dark : light })) }), { name: theme-storage } ) );8.2 导出选择器 Hookconst useStore create(...); // 导出自定义选择器 export const useCount () useStore(state state.count); export const useIncrement () useStore(state state.increment); export const useDecrement () useStore(state state.decrement); // 使用 function Component() { const count useCount(); const increment useIncrement(); // ... }8.3 重置 Storeconst initialState { count: 0, user: null, todos: [] }; const useStore create((set) ({ ...initialState, reset: () set(initialState), increment: () set((state) ({ count: state.count 1 })), setUser: (user) set({ user }), addTodo: (text) set((state) ({ todos: [...state.todos, { id: Date.now(), text }] })) }));8.4 类型安全TypeScriptinterfaceUser{id:number;name:string;}interfaceUserState{user:User|null;setUser:(user:User|null)void;}constuseUserStorecreateUserState()(persist((set)({user:null,setUser:(user)set({user})}),{name:user-storage}));8.5 条件持久化const useStore create( persist( (set) ({ user: null, rememberMe: false }), { name: auth-storage, // 只有勾选记住我时才持久化 partialize: (state) state.rememberMe ? { user: state.user } : {} } ) );九、练习题创建一个带持久化的主题 Store创建一个带 DevTools 的计数器 Store创建一个使用 immer 简化更新的 Todo Store十、小结中间件用途配置persist持久化存储{ name: key }devtools调试支持{ name: StoreName }immer简化更新直接修改状态组合使用多中间件叠加嵌套包裹