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

React使用Apollo Client解构useQuery结果刷新报undefined错误

报错信息

Uncaught TypeError: Cannot destructure property 'slumpMedias' of '(0 , apollo_client__WEBPACK_IMPORTED_MODULE_4_.useQuery)(...)' as it is undefined.

问题背景

React.js项目采用WordPress + GraphQL作为Headless CMS搭建后端能力,项目配置已校验无误,通过Apollo Client和gql实现GraphQL查询调用。

最后一次可正常运行的代码
import { useQuery } from "@apollo/client";
import gql from "graphql-tag";

const GET_ALL_MEDIA = gql`
  query MyQuery {
    slumpMedias(first: 100) {
      edges {
        node {
          title
          slumpMeta {
            image {
              mediaItemUrl
            }
            audio1 {
              mediaItemUrl
            }
          }
        }
      }
    }
  }
`;

function Items() {

  const { loading, error, data } = useQuery(GET_ALL_MEDIA);
  console.log(data);

  if (loading) return <h1>Loading..</h1>;
  if (error) return <h1>Loading..</h1>;

  return <div>Hello</div>;
}

该版本运行时控制台打印的data结构正常,可成功获取数据:

>slumpMedias: {…}}
 >slumpMedias: 
    >edges: (17) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] 
     >[[Prototype]]: Object
  >[[Prototype]]: Object
问题现象

接口调用验证通过后,为简化后续数据调用逻辑,对返回对象做深层解构,调整后的查询代码如下:

const {
  loading,
  error,
  data: {
    slumpMedias: { edges },
  },
} = useQuery(GET_ALL_MEDIA);

console.log(edges);

代码保存后浏览器热更新自动加载页面,控制台可正常打印预期的edges数组,包含17条数据:

(17) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

但手动刷新页面时,项目提示编译成功,页面完全白屏,抛出如下错误栈:

Items.js:34 Uncaught TypeError: Cannot destructure property 'slumpMedias' of '(0 , _apollo_client__WEBPACK_IMPORTED_MODULE_4__.useQuery)(...)' as it is undefined.
    at Items (Items.js:34:1)
    at renderWithHooks (react-dom.development.js:16175:1)
    at mountIndeterminateComponent (react-dom.development.js:20913:1)
    at beginWork (react-dom.development.js:22416:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4161:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4210:1)
    at invokeGuardedCallback (react-dom.development.js:4274:1)
    at beginWork$1 (react-dom.development.js:27405:1)
    at performUnitOfWork (react-dom.development.js:26513:1)
    at workLoopSync (react-dom.development.js:26422:1)

已确认graphql-tag依赖引入正确,问题仍未解决。

根本原因

报错核心原因是组件首次渲染时请求未完成,data字段为undefined:

  • Apollo Client的useQuery钩子在请求初始阶段、数据未返回时,返回值中的data字段默认是undefined。
  • 热更新场景下能正常运行,是因为热更新触发时上一次请求的结果已经存在于Apollo缓存中,组件重渲染时直接读取缓存数据,不会出现data为undefined的情况。
  • 手动刷新页面时缓存被清空,组件首次渲染时请求处于pending状态,data为undefined,此时直接深层解构data: { slumpMedias: { edges } },等价于尝试从undefined上读取slumpMedias属性,直接抛出类型错误,中断组件渲染导致白屏。
  • 初始版本代码不报错,是因为初始版本仅解构第一层的loading/error/data,没有在解构阶段直接读取data内部属性,等loading判断通过、数据返回后才操作data,不会触发解构错误。
修复方案

方案1:解构时设置默认值(改动最小)

给深层解构的层级设置空对象默认值,避免undefined解构报错:

const {
  loading,
  error,
  data: {
    slumpMedias: { edges } = {},
  } = {},
} = useQuery(GET_ALL_MEDIA);

加载阶段edges值为undefined,配合原有的loading/error判断逻辑即可正常运行,不会打断渲染。

方案2:分层处理(逻辑更清晰,更推荐)

先解构第一层返回值,等加载、错误状态校验通过、确认data存在后,再解构内部属性:

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

  if (loading) return <h1>Loading..</h1>;
  if (error) return <h1>Load failed</h1>;
  // 逻辑走到此处时data一定存在,解构不会报错
  const { slumpMedias: { edges } } = data;
  console.log(edges);

  return <div>Hello</div>;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:30:57