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
相关产品推荐
相关产品推荐

