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

GraphQL查询结果嵌入Object崩溃、嵌入JSX正常的问题排查

问题根因

useQuery 是异步执行的Hook,组件首次渲染时GraphQL请求还在发送阶段,此时返回的data初始值为undefined。你在组件顶层同步定义objects数组时直接读取data.slumpMedias,等价于执行undefined.slumpMedias,直接抛出类型错误中断React渲染流程,导致白屏。

你之前把路径写在JSX里看似能正常运行,是因为开发环境热更新、Apollo本地缓存命中时,组件首次渲染就能拿到缓存的旧数据,没有触发data为undefined的初始状态;硬刷新页面后缓存被清空,首次渲染必然进入loading状态,就稳定复现报错。你观察到的「短暂渲染正确内容」是请求返回后触发重渲染的预期结果,但首次渲染的报错已经让整个组件树崩溃,重渲染逻辑根本没有机会执行。

修复方法
  1. 必须先处理请求的loading、error状态,在请求未完成、请求出错时不要访问data下的任何字段
  2. 确认data存在后再构建自定义数据结构,不要在组件顶层无任何判断就直接访问data的深层属性

修复后的可运行代码:

function Items() {
  const { loading, error, data } = useQuery(GET_ALL_MEDIA);

  // 加载状态返回占位
  if (loading) return <div>内容加载中</div>;
  // 请求异常返回错误提示
  if (error) return <div>加载失败:{error.message}</div>;

  // 执行到此处时data已完成赋值,可安全读取字段
  const objects = [
    {
      id: 0,
      title: data.slumpMedias.edges[6].node.title,
      image: "/images/1.png",
      sound: "/default-sound.mp3",
      items: [],
    },    
  ];

  return <Display objects={objects} />;
}

如果不想提前中断渲染,也可以用可选链+空值兜底避免读取undefined属性:

function Items() {
  const { loading, error, data } = useQuery(GET_ALL_MEDIA);

  // data不存在时objects默认为空数组
  const objects = data?.slumpMedias ? [
    {
      id: 0,
      title: data.slumpMedias.edges[6].node.title,
      image: "/images/1.png",
      sound: "/default-sound.mp3",
      items: [],
    },    
  ] : [];

  if (loading) return <div>内容加载中</div>;
  if (error) return <div>加载失败:{error.message}</div>;

  return <Display objects={objects} />;
}

注意:你最开始写的直接在JSX中读取data.slumpMedias.edges[5].node.title的代码本身也存在同样的隐患,只是之前缓存命中没触发报错,同样需要加状态判断或者可选链兜底,否则清空缓存硬刷新时一样会崩溃。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 21:01:16