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

初始化ZegoCloud数据时Redux检测到非序列化值的解决求助

修复Redux存储ZegoUIKitPrebuilt实例的序列化错误

问题原因

Redux要求全局状态必须是可序列化的数据类型(比如普通对象、数组、字符串、数字等),而ZegoUIKitPrebuilt.create()返回的是包含内部方法、原型链的类实例,属于不可序列化的值,直接存入Redux就会触发"A non-serializable value was detected in the state"错误。

修复方案

方案1:用React Context管理Zego实例(最推荐)

把Zego实例放到React Context中,替代Redux存储,既能跨组件共享,又符合React状态管理逻辑。

  1. 创建ZegoContext文件:
// ZegoContext.js
import { createContext, useContext } from 'react';

const ZegoContext = createContext(null);

export const ZegoProvider = ZegoContext.Provider;
export const useZego = () => useContext(ZegoContext);
  1. 修改Home.js,用Provider包裹组件并传入实例:
// Home.js
import { ZegoProvider } from './ZegoContext';
import { useState } from 'react';

function Home() {
  const [zp, setZp] = useState(null);

  useEffect(() => {
    if (currentUser) {
      init();
    }
  }, [currentUser]);

  async function init() {
    const userID = currentUser?.Username;
    const userName = 'userName' + userID;
    const { token } = await generateToken('https://node-express-vercel-master-one.vercel.app', userID);
    const KitToken = ZegoUIKitPrebuilt.generateKitTokenForProduction(1980920521, token, null, userID, userName);
    const newZp = ZegoUIKitPrebuilt.create(KitToken);
    newZp.addPlugins({ ZIM });
    setZp(newZp);
  }

  if (!zp) return <div>加载中...</div>;

  return (
    <ZegoProvider value={zp}>
      {/* 首页内容 */}
    </ZegoProvider>
  );
}
  1. 在调用组件中用useZego获取实例:
// 调用组件
import { useZego } from './ZegoContext';

function CallComponent() {
  const zp = useZego();
  const { coachId } = useParams();
  const chatId = useSelector((state) => state.chat.chatId);

  function handleSend(callType) {
    if (!zp) return;
    const targetUser = {
      userID: user?.username,
      userName: user?.username,
    };
    zp.sendCallInvitation({
      callees: [targetUser],
      callType: callType,
      timeout: 60,
    })
    .then((res) => console.warn(res))
    .catch((err) => console.warn(err));
  }

  {/* 组件其他内容 */}
}

方案2:在需要使用的地方动态创建实例(适合无需跨多组件共享的场景)

如果仅在少数组件中使用Zego实例,可以把初始化逻辑封装成可复用函数,需要时直接创建使用,避免存入Redux。

// 封装初始化函数
async function getZegoInstance(userID) {
  const userName = 'userName' + userID;
  const { token } = await generateToken('https://node-express-vercel-master-one.vercel.app', userID);
  const KitToken = ZegoUIKitPrebuilt.generateKitTokenForProduction(1980920521, token, null, userID, userName);
  const zp = ZegoUIKitPrebuilt.create(KitToken);
  zp.addPlugins({ ZIM });
  return zp;
}

// 在调用组件中使用
function CallComponent() {
  const [zp, setZp] = useState(null);
  const user = useSelector(state => state.user);

  useEffect(() => {
    if (user?.username) {
      getZegoInstance(user.username).then(setZp);
    }
  }, [user]);

  function handleSend(callType) {
    if (!zp) return;
    const targetUser = {
      userID: user?.username,
      userName: user?.username,
    };
    zp.sendCallInvitation({
      callees: [targetUser],
      callType: callType,
      timeout: 60,
    })
    .then(res => console.warn(res))
    .catch(err => console.warn(err));
  }

  {/* 组件其他内容 */}
}

方案3:临时禁用Redux的序列化检查(不推荐)

如果一定要用Redux存储实例,可以关闭Redux Toolkit的序列化检查,但会导致时间旅行调试、状态持久化等功能失效,仅作为临时应急方案。

修改store配置:

// store.js
import { configureStore } from '@reduxjs/toolkit';
import chatSlice from './chatSlice';

export const store = configureStore({
  reducer: {
    chat: chatSlice,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredPaths: ['chat.zego'],
      },
    }),
});

内容的提问来源于stack exchange,提问作者Quang Phú Nguyễn Hoàng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:07:47