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

React Query useQuery数据处理报错:无法读取undefined的products属性

解决React Query useQuery中Cannot read properties of undefined (reading 'products')错误

问题描述

我编写了一个cleanResponse辅助函数,用于清理useQuery调用API返回的响应数据:

export const cleanResponse = function (data) {
  let x = [];
  let y = [];

  data.forEach((item) => {
    x.push(item.title);
    y.push(item.price);
  });
  return { titles: x, prices: y };
};

在主组件中,我使用useQuery获取数据后调用该函数处理,以便用于图表绘制:

const {
    data: products,
    isLoading,
    isError,
  } = useQuery(['products'], () => {
    return axios('https://dummyjson.com/products/').then((res) => res.data);
  });

  const cleanData = cleanResponse(products.products);
  const titles = cleanData?.titles;
  const prices = cleanData?.prices;

随后将处理后的数据传入BarChart组件:

<BarChart titles={titles} prices={prices} />

现在出现错误:

Uncaught TypeError: Cannot read properties of undefined (reading 'products')

请问我遗漏了什么?cleanResponse函数是否需要设为异步,因为它接收的是API返回的数据?


解决方案

错误原因

useQuery在初始渲染时,data(即你重命名的products)是undefined——因为API请求还在异步进行中,尚未返回结果。此时直接访问products.products,就会触发"读取undefined的属性"的错误。

修复方式

你需要先处理数据加载的状态,确保在数据存在后再执行数据清理逻辑:

方式一:基于加载状态做条件渲染

const {
    data: products,
    isLoading,
    isError,
  } = useQuery(['products'], () => {
    return axios('https://dummyjson.com/products/').then((res) => res.data);
  });

// 仅当products存在时才处理数据,否则返回空数组结构
const cleanData = products ? cleanResponse(products.products) : { titles: [], prices: [] };
const titles = cleanData.titles;
const prices = cleanData.prices;

// 先处理加载/错误状态
if (isLoading) return <div>加载中...</div>;
if (isError) return <div>数据加载失败</div>;

return <BarChart titles={titles} prices={prices} />;

方式二:用可选链+默认值避免报错

const {
    data: products,
    isLoading,
    isError,
  } = useQuery(['products'], () => {
    return axios('https://dummyjson.com/products/').then((res) => res.data);
  });

// 用可选链确保products存在再访问products.products,否则传入空数组
const cleanData = cleanResponse(products?.products || []);
const titles = cleanData.titles;
const prices = cleanData.prices;

// 仍需处理加载/错误状态,避免图表接收空数据时异常
if (isLoading) return <div>加载中...</div>;
if (isError) return <div>数据加载失败</div>;

return <BarChart titles={titles} prices={prices} />;

关于cleanResponse是否需要异步的问题

不需要。cleanResponse只是同步处理内存中已有的数据,API请求的异步逻辑已经由useQuery和axios处理完成。当products存在时,它是已经解析完成的同步数据,因此cleanResponse保持同步即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:54:36