如何解决React中‘undefined is not an object (evaluating 'data.products.map')’错误?
问题分析与解决方案
核心问题
- 数据未就绪时的空值访问:React Query首次调用时
data初始状态为undefined,你设置的默认值[]是数组类型,若Django API返回的是带products字段的对象,空数组本身没有products属性,直接访问会触发报错。 - 变量名书写错误:你尝试的
data.products && products.map中,products是未定义变量,正确写法应为data.products.map。 - 数据结构不匹配:临时改为
data.map能生效,说明Django API返回的是直接的产品数组,而非包含products字段的嵌套对象,原代码的data.products本身就不存在。
针对性解决方案
方案1:匹配API返回结构(推荐)
如果Django REST API返回的是直接的产品数组(格式示例:[{id:1,...}, {id:2,...}]),修改useAllProducts.js如下:
import { useQuery } from "react-query"; import { loadProducts } from "./api/api"; function useAllProducts() { const { data = [], isLoading, isError } = useQuery("products", loadProducts); // 加载中返回空数组,避免提前渲染报错 if (isLoading) return []; // 错误状态返回空数组或自定义错误处理 if (isError) return []; return data.map(({ id }) => id); } export default useAllProducts;
方案2:适配嵌套结构的API返回
如果Django API返回的是{products: [...], count: ...}这类嵌套结构,修正初始默认值并处理加载状态:
import { useQuery } from "react-query"; import { loadProducts } from "./api/api"; function useAllProducts() { // 初始默认值设为包含空products数组的对象,而非空数组 const { data = { products: [] }, isLoading, isError } = useQuery("products", loadProducts); if (isLoading || isError) return []; return data.products.map(({ id }) => id); } export default useAllProducts;
方案3:优化API层的错误处理(可选)
当前api.js未处理HTTP错误,可添加基础错误捕获,让React Query能正确识别错误状态:
const wrappedFetch = (...args) => { return fetch(...args) .then((res) => { if (!res.ok) { throw new Error(`请求失败: ${res.status}`); } return res.json(); }) .catch((err) => { console.error("API请求错误:", err); // 抛出错误让React Query捕获并标记为isError throw err; }); };
关键注意事项
- 必须利用React Query提供的
isLoading/isError状态,确保数据就绪后再执行数组操作,杜绝空值访问。 - 先明确Django API的返回结构(数组/嵌套对象),再编写对应逻辑,避免试探性修改代码。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

