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

Apollo-client中useLazyQuery调用refetch时偶尔返回undefined问题排查

问题原因
  • 首次调用refetch前未触发过lazyQuery的执行函数:useLazyQuery返回的refetch方法仅在你至少调用过一次触发函数(也就是你代码里的getById)后才会被正确初始化,未执行过getById就调用refetch的话,refetch本身就是undefined,await undefined自然不会有返回值。
  • 未捕获异常导致逻辑中断:你的refetch调用没有被try/catch包裹,当出现网络中断、参数错误等异常时,refetch会直接抛出错误中断执行,不会返回任何值,你拿到的结果就是undefined。
  • 组件生命周期问题:如果refetch还在pending状态时父组件Homescreen卸载、或者子组件Viewer卸载,pending的请求resolve后会返回空值。
  • 部分旧版本Apollo Client存在已知bug:缓存命中且未指定强制走网络的fetchPolicy时,refetch偶尔会出现返回值为空的问题。
解决方案
  • 增加前置校验和异常捕获,避免空调用和未捕获错误:
const refetchObjects= async () => {
  // 先校验refetch是否存在
  if (!refetch) return
  try {
    const res = await refetch();
    // 校验返回值是否存在
    if (!res) return
    const { error, data } = res
    if (error) { 
      console.log(error);
      return
    }
    if (data) {
      // 注意:如果activeObject是普通变量而非useState/useRef存储的值,更新后不会触发组件重渲染
      activeObject = data.getRegionById;
    }
  } catch (e) {
    console.log('refetch执行失败', e)
  }
}
  • 优先用触发函数getById替代refetch,稳定性更高:你可以直接把getById从父组件传给子组件,每次调用时传入查询id,无需等待首次执行就能调用:
// 子组件调用逻辑
const refetchObjects= async () => {
  try {
    const { error, data } = await getById({ variables: { id: 你的查询ID } });
    if (error) { console.log(error);}
    if (data) {
        activeObject = data.getRegionById;
    }
  } catch (e) {
    console.log(e)
  }
}
  • 给lazyQuery配置强制走网络的请求策略,避免缓存异常:
const [getById, {loading, error, data, refetch}] = useLazyQuery(GET_BY_ID, {
  fetchPolicy: 'network-only',
  notifyOnNetworkStatusChange: true
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 06:15:00