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

使用useSWR出现Cannot convert undefined or null to object错误排查

问题

在Next.js中使用useSWR,API路由通过异步查询数据库获取数据。前端代码如下:

const fetcher = (url: string) => axios.get(url).then((r) => r.data);

const { data, error } = useSWR("/api/model?data=" + selectedMatch, fetcher, {
  refreshInterval: 1000,
});

执行console.log(data)和console.log(typeof(data))能正常打印出对象,但添加console.log(Object.keys(data))后,出现Cannot convert undefined or null to object错误,且typeof(data)变为undefined。尝试改用useSWRImmutable但无效。

API路由的数据库查询代码如下:

export const GET = async (req: NextRequest) => {
  await connectToDB();
  const matchString: String = req.nextUrl.searchParams.get("data");
  const events: any = {}; 
  const promises = matchString.split(",").map(async (match: string) => {
    try {
      events[match] = await Events.find({ name: match }).then((res) => res[0]);
    } catch (error) {
      events[match] = error;
      console.log("model/route.js error")
    }
  })

  await Promise.all(promises)
  return new Response(JSON.stringify(events), { status: 200 });
};

错误原因

  • useSWR异步加载特性导致初始值为空:useSWR是异步获取数据,组件首次渲染时data为undefined。单独打印data时,浏览器控制台会自动更新显示最终的有效值,但直接调用Object.keys(data)时,初始渲染阶段data仍未undefined,触发类型错误。错误抛出后会干扰后续状态更新,导致typeof(data)也显示为undefined。
  • API路由存在空值隐患:req.nextUrl.searchParams.get("data")可能返回null(比如selectedMatch为空时),此时调用matchString.split(",")会直接报错,API返回的响应不再是预期的对象,进一步导致前端数据异常。
  • API错误处理的序列化问题:catch块中直接将error对象赋值给events[match],而Error对象无法被JSON.stringify正常序列化,可能导致前端接收到的数据不是合法对象。

解决办法

前端侧修复

在访问data的属性或调用Object.keys前,必须先判断data是否存在:

// 方式1:条件判断后执行
if (data) {
  console.log(Object.keys(data));
}

// 方式2:可选链+空值合并简化写法
console.log(data ? Object.keys(data) : []);

API路由侧修复

  1. 处理matchString为null的情况,避免调用split时报错;
  2. 修正错误对象的序列化问题,将error替换为可序列化的内容:
export const GET = async (req: NextRequest) => {
  await connectToDB();
  const matchString = req.nextUrl.searchParams.get("data");
  const events: any = {}; 

  // 处理matchString为null的情况
  if (!matchString) {
    return new Response(JSON.stringify(events), { status: 200 });
  }

  const promises = matchString.split(",").map(async (match: string) => {
    try {
      const res = await Events.find({ name: match });
      events[match] = res[0];
    } catch (error) {
      // 用null或错误信息字符串替代Error对象,确保可序列化
      events[match] = null;
      console.log("model/route.js error:", error);
    }
  })

  await Promise.all(promises);
  return new Response(JSON.stringify(events), { status: 200 });
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 12:55:31