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

使用Apollo的useQuery出现undefined报错的处理方案咨询

useQuery空值问题优化方案

你可以根据业务场景选择以下几种处理方式,不需要在每个使用useQuery的组件中单独重复写loading判断:

1. 利用内置状态前置校验

useQuery本身会返回loading、error字段,你可以在返回业务UI前先处理加载、异常状态,走到业务逻辑分支时data必然已加载完成,不需要额外做空值判断:

import {useQuery} from '@apollo/react-hooks';
import resolvers from '../../resolvers';

const DashboardComponent = () => {
  const {data, loading, error} = useQuery(resolvers.ReturnAllMovies);
  // 前置处理状态
  if (loading) return <Loading />;
  if (error) return <ErrorTip content={error.message} />;
  
  // 此处data必然存在,无需可选链
  const movies = data.movies;

  return (
    <React.Fragment>
      <DashboardMovieOverviewMenu />
      { movies.length > 0 && <MovieOverview /> }
    </React.Fragment>
  );
};

export default DashboardComponent;

2. 封装通用逻辑复用

如果项目中大量组件用到useQuery,可以将加载、异常的通用处理逻辑封装成自定义Hook或者高阶组件,一次封装多处调用:

自定义Hook示例:

// 全局封装
const useSafeQuery = (query, options) => {
  const res = useQuery(query, options);
  if (res.loading) return { ...res, data: options?.defaultData ?? {} };
  if (res.error) throw res.error;
  return res;
}

// 组件内使用
const { data } = useSafeQuery(resolvers.ReturnAllMovies, { defaultData: { movies: [] } });
const movies = data.movies;

你也可以直接开启Apollo的Suspense模式,配合React的Suspense组件统一处理全局加载态,组件内部完全不需要感知loading状态。

3. 配置初始值省略校验

对于列表类简单查询场景,可以直接给useQuery配置initialData参数,初始化时就给data填充默认结构,自然不会出现undefined问题:

const { data } = useQuery(resolvers.ReturnAllMovies, {
  initialData: { movies: [] }
});
const movies = data.movies;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:51:00