讲师中心 微信公众号
AI工具推荐 视频效率加速

Zustand Persist 中函数丢失问题的完整解决方案

浅静大大_2079

浅静大大_2079

发布时间:2026-02-03 09:33:12

|

365人浏览过

|

来源于php中文网

原创

Zustand Persist 中函数丢失问题的完整解决方案

zustand 的 `persist` 中间件在页面刷新后会丢失 store 中定义的方法(如 `setcolor`),因其仅持久化可序列化的状态值,而函数无法被 json 序列化,导致重 hydration 后方法变为 `undefined`。

这是 Zustand persist 中间件的一个关键设计约束:它只负责持久化 state 数据(即 plain object 属性),而不会、也不能持久化函数、getter、class 实例或任何不可序列化内容。当你将整个 store 工厂函数(如 (set) => ({ primaryColor, setColor, todoColor }))直接传给 persist() 时,Zustand 在首次初始化后会立即对返回的对象进行序列化 —— 此时 setColor 和 todoColor 作为函数被自动忽略,仅保留 primaryColor: "#247fff" 这类基础值。当页面刷新并从 localStorage 恢复状态时,store 仅能还原出 { primaryColor: "#247fff" },而 setColor 等方法已不复存在,因此调用时报错 TypeError: Cannot read properties of undefined。

✅ 正确用法:persist 必须包裹整个 create() 调用,而非单个 slice 工厂函数

你当前的写法是错误的:

chartjs-reporter
chartjs-reporter

此技能用于在用户需要将结构化数据(查询结果、CSV 摘要、JSON 记录或 Python 字典/列表)转换为独立的 HTML 页面时使用。

下载
// ❌ 错误:对 slice 工厂函数单独 persist → 函数被丢弃
export const GlobalStoreSlice = persist(
  (set) => ({ /* ...actions... */ }),
  { name: "primaryColor" }
);

正确做法是:先组合所有 slice,再对最终的 store 使用 persist(且通常与 devtools 一同置于顶层中间件链中):

// ✅ 正确:在 create() 顶层应用 persist,确保 action 始终可用
import { create } from "zustand";
import { devtools, persist } from "zustand/middleware";
import { LoginStoreSlice } from "@/stores/login";
import { createBearSlice, createFishSlice } from "@/stores/global";

// 注意:GlobalStoreSlice 不再是 persist(...),而是纯 factory
export const GlobalStoreSlice = (set: any) => ({
  primaryColor: "#247fff",
  setColor: (color: string) => set(() => ({ primaryColor: color })),
  todoColor: () => set(() => ({ primaryColor: "black" })),
});

export const UseStore = create(
  devtools(
    persist(
      (...a) => ({
        ...LoginStoreSlice(...a),
        ...GlobalStoreSlice(...a),
        ...createBearSlice(...a),
        ...createFishSlice(...a),
      }),
      {
        name: "app-storage", // ⚠️ 全局唯一 key,不要用 slice 名
        partialize: (state) => ({
          // ✅ 显式指定需持久化的字段(推荐)
          primaryColor: state.primaryColor,
          userInfo: state.userInfo,
        }),
      }
    )
  )
);

? 关键要点说明

  • persist 必须作用于 create(...) 的最终 reducer,这样才能保证每次 set 调用都基于完整、带方法定义的 store 结构;
  • 不要对单个 slice 工厂函数调用 persist() —— 它不是为 slice 设计的“装饰器”,而是为整个 store 提供持久化能力的中间件;
  • 使用 partialize 显式声明要持久化的字段,避免意外持久化不可序列化内容(如函数引用、Promise、Date 对象等);
  • 若需为不同 slice 设置独立存储名或逻辑,应通过 partialize + 条件判断实现,而非拆分 persist 调用;
  • devtools 和 persist 的顺序建议为 devtools(persist(...)),以确保调试工具能捕获持久化事件。

? 额外建议:类型安全增强(TypeScript)

为避免 any 类型,可定义统一 store 类型:

type StoreState = ReturnType<typeof LoginStoreSlice> &
  ReturnType<typeof GlobalStoreSlice> &
  ReturnType<typeof createBearSlice> &
  ReturnType<typeof createFishSlice>;

export const UseStore = create<StoreState>()(
  devtools(
    persist(
      (...a) => ({
        ...LoginStoreSlice(...a),
        ...GlobalStoreSlice(...a),
        ...createBearSlice(...a),
        ...createFishSlice(...a),
      }),
      {
        name: "app-storage",
        partialize: (state) => ({
          primaryColor: state.primaryColor,
          userInfo: state.userInfo,
        }),
      }
    )
  )
);
✅ 总结:Zustand persist 不是“让任意对象持久化”的万能工具,而是“为 store 的 state 字段提供自动存取能力”的中间件。只要将它放在 create() 最外层,并配合 partialize 精确控制持久化范围,就能彻底规避函数丢失问题 —— 无需更换状态管理库。

热门AI工具

更多
UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

292

2026.02.13

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

520

2026.02.25

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

371

2026.03.13

TypeScript 全栈开发进阶指南
TypeScript 全栈开发进阶指南

面向有 JavaScript 基础的开发者,深入讲解 TypeScript 的类型系统与全栈开发实践。

286

2026.06.03

TypeScript Node.js 全栈工程化与Monorepo架构实践
TypeScript Node.js 全栈工程化与Monorepo架构实践

本专题围绕 TypeScript 在 Node.js 全栈开发中的工程化实践展开,系统讲解 Monorepo 架构设计、包管理策略、模块复用机制以及服务端与前端统一类型系统的构建方法。通过真实项目案例,帮助开发者提升大型全栈项目的可维护性与协作效率。

638

2026.06.16

什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

669

2024.05.11

Golang 中间件开发与微服务架构
Golang 中间件开发与微服务架构

本专题系统讲解 Golang 在微服务架构中的中间件开发,包括日志处理、限流与熔断、认证与授权、服务监控、API 网关设计等常见中间件功能的实现。通过实战项目,帮助开发者理解如何使用 Go 编写高效、可扩展的中间件组件,并在微服务环境中进行灵活部署与管理。

624

2025.12.18

ThinkPHP中间件机制与请求拦截处理实践
ThinkPHP中间件机制与请求拦截处理实践

本专题围绕 ThinkPHP 中间件体系展开,深入讲解中间件的定义、注册与执行流程。内容包括全局中间件与路由中间件的区别、请求前后处理逻辑、自定义中间件开发以及权限验证与日志处理应用。通过实际案例,帮助开发者掌握中间件在项目中的核心作用与最佳实践。

438

2026.03.31

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

40

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 21.1万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 4.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn