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

如何在Zustand状态中存储带方法的对象并访问其方法?

从Zustand状态获取对象后无法访问其方法,如何正确存储带方法的对象?

问题场景

将Firebase Auth返回的User对象存入Zustand状态后,无法访问其原型方法(如updateEmail),相关代码如下:

Store定义(store.jsx)

import create from "zustand";
import { persist } from "zustand/middleware";
import { cloneDeep } from "lodash";

const initialState = {
  user: undefined,
  profile: undefined,
}

let store = (set) => ({
  ...initialState,
  setUser: (user) => set((state) => ({ user: cloneDeep(user) })),
  setProfile: (profile) => set((state) => ({ profile: profile })),
  logout: () => {set(initialState)},
});
store = persist(store);
export const useUserStore = create(store);

设置状态(file2.jsx)

import { useUserStore } from "../../store";

const setUser = useUserStore((state) => state.setUser);

useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged((user) => {
     // 此时user包含所有属性和方法
      setUser(user);
    });
    return () => unsubscribe();
  }, []);

访问状态(file2.jsx)

import { useUserStore } from "../../../store/userStore";

const user = useUserStore((state) => state.user);

// 报错:updateEmail方法未定义
user.updateEmail()

问题原因

核心问题出在cloneDeep(user):Lodash的cloneDeep仅能复制对象的可枚举属性,无法保留对象的原型链及原型上的方法。Firebase User是带原型方法的实例,经过深度克隆后原型链被切断,自然访问不到updateEmail这类方法。另外,若使用了persist中间件,持久化时的JSON序列化也会丢失函数和原型信息。

解决方案

方案1:直接存储原始对象(非持久化场景)

去掉cloneDeep,直接存入原始User实例:

// 修改store中的setUser方法
setUser: (user) => set((state) => ({ user })),

注意:此方案仅适用于不需要持久化的场景,因为persist中间件的JSON序列化会丢失方法。

方案2:拆分存储属性与方法调用(持久化场景)

如果需要持久化用户信息,只存储可序列化的核心属性,调用方法时直接使用Firebase Auth的currentUser:

// 修改setUser,仅存储需要的属性
setUser: (user) => set((state) => ({ 
  user: {
    uid: user.uid,
    email: user.email,
    displayName: user.displayName
    // 按需添加其他可序列化属性
  } 
})),

// 调用方法时直接使用auth.currentUser
auth.currentUser.updateEmail(newEmail);

方案3:直接使用Firebase Auth的currentUser

无需将User存入Zustand,直接通过auth.currentUser访问实例及所有方法,避免状态存储带来的原型链丢失问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:01:18