You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js+TypeScript中Zustand嵌套对象函数运行时报错'not a function'排查

问题原因与修复方案:Zustand persist 嵌套函数抛出"not a function"错误

问题原因

Zustand 的persist中间件默认会将状态序列化为 JSON 格式存储(如 localStorage),而函数无法被 JSON 序列化。当你把toggle_slide_over嵌套在session_setup对象内部时,这个函数会被 persist 过程中的序列化操作丢弃;从存储恢复状态时,session_setup.toggle_slide_over会变成undefined,调用自然会抛出"not a function"错误。

而将函数放在对象外部时,Zustand 会将其视为状态的动作(actions),不会被 persist 序列化,因此能正常保留。

修复方法

方案1:用partialize排除嵌套函数(保留原有结构)

通过persist的partialize配置,指定仅序列化需要持久化的原始数据(如slide_over_open),排除嵌套的函数:

const doPersist = persist(
  (set) => ({
    session_setup: {
      slide_over_open: false,
      toggle_slide_over: (new_toggle_state) => set(
        produce(state => { state.session_setup.slide_over_open = new_toggle_state })
      ),
      // 其他session_setup属性...
    },
    // 其他顶层状态...
  }),
  {
    name: 'my-app-store', // 存储键名
    partialize: (state) => ({
      session_setup: {
        // 只序列化需要持久化的原始数据,跳过函数
        slide_over_open: state.session_setup.slide_over_open
        // 其他需要持久化的session_setup属性...
      }
      // 其他需要持久化的顶层状态...
    })
  }
)

这样 persist 只会处理你指定的原始数据,嵌套函数不会被序列化,能正常保留。

方案2:拆分状态为独立 Slice(推荐)

如果状态结构复杂,推荐用 Zustand 的 Slice 模式,将session_setup拆分为独立的状态片段,函数放在顶层,既避免序列化问题,也让状态结构更清晰:

// 定义session_setup的独立Slice
const createSessionSetupSlice = (set) => ({
  session_slide_over_open: false,
  toggleSessionSlideOver: (new_toggle_state) => set(
    produce(state => { state.session_slide_over_open = new_toggle_state })
  ),
  // 其他session_setup相关状态和方法...
})

// 组合Slice创建Store
const doPersist = persist(
  (set) => ({
    ...createSessionSetupSlice(set),
    // 其他Slice...
  }),
  { name: 'my-app-store' }
)

这种方式无需额外配置,且命名更简洁,多层嵌套场景下也不会出现冗长命名问题。

方案3:依赖初始状态合并逻辑(不推荐)

如果坚持保留嵌套结构,确保初始状态中session_setup始终包含toggle_slide_over函数。persist 恢复状态时,只会覆盖序列化的属性(如slide_over_open),初始状态里的函数会被保留。但这种方式依赖 persist 的合并逻辑,若存储的状态意外包含toggle_slide_over的序列化值(如null),仍会覆盖函数,可靠性较低。

验证修复

修改后,正常获取嵌套函数即可正常调用:

const toggle_slide_over = useMyAppStore(state => state.session_setup.toggle_slide_over)

内容的提问来源于stack exchange,提问作者kroflic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:21:33