如何为分离状态与动作的Zustand实现持久化?
解决Zustand添加persist中间件后Actions失效的问题
问题根源
两个核心原因导致setAccessToken is not a function这类报错:
- persist中间件会包装原始store,返回的新store类型结构与原始store不同,你之前的自定义类型无法正确识别包装后的结构,导致类型推断错误。
- persist默认序列化整个state对象,而actions作为函数无法被序列化,从存储恢复后会变成
undefined。
修复步骤
1. 调整自定义类型适配persist
修改你的类型定义,确保能正确识别persist包装后的store:
/** * 提取Zustand store的状态类型,兼容persist包装后的实例 */ export type ExtractState<S> = S extends { getState: () => infer T; } ? T : never; // 先定义完整的store类型(包含persist包装后的结构) type AuthStore = ReturnType<typeof createAuthStore>; // 基于包装后的store类型推断Params type Params<U> = Parameters<typeof useStore<AuthStore, U>>;
2. 配置persist排除actions字段
在persist配置中使用partialize只持久化需要的状态字段,避免actions被序列化:
import { create } from 'zustand'; import { persist } from 'zustand/middleware'; const createAuthStore = () => create(persist( (set) => ({ accessToken: null, actions: { setAccessToken: (token: string | null) => set({ accessToken: token }), // 其他action方法 }, }), { name: 'auth-storage', // 本地存储的键名 // 仅持久化accessToken,排除actions partialize: (state) => ({ accessToken: state.accessToken }) } )); export const useAuthStore = createAuthStore();
3. 验证调用方式
确保调用actions时的类型正确,示例:
// 正确调用方式 const setAccessToken = useAuthStore(state => state.actions.setAccessToken); setAccessToken('new-token');
内容的提问来源于stack exchange,提问作者Agent Smith
相关产品推荐
相关产品推荐

