React订餐项目调用Swiggy API出现map读取未定义错误,请求修复
修复方案:解决Swiggy API调用的TypeError及餐厅卡片显示问题
错误原因分析
- Body.js中API数据路径错误:你尝试访问
json.data.cards[5].card.card.gridElements.infoWithStyle.restaurants.info,但restaurants本身是一个数组,数组没有info属性,导致ListOfRestaurants被设置为undefined,调用map时触发类型错误。 - 未处理API数据不存在的情况:直接硬编码访问数组索引(如
cards[5])和深层嵌套属性,一旦API返回结构变化或请求失败,会导致属性访问失败。 - RestaurantCard组件数据访问逻辑错误:组件接收的
resData已经是单个餐厅对象,但你仍在重复访问整个API的嵌套路径,且存在未定义变量restaurants的拼写错误。
分步修复代码
1. 修正Body.js
import { useState, useEffect } from "react"; import RestaurantCard from "./RestaurantCard"; const Body = () => { const [listOfRestaurants, setListOfRestaurants] = useState([]); useEffect(() => { fetchData(); }, []); const fetchData = async () => { try { const data = await fetch( "https://www.swiggy.com/dapi/restaurants/list/v5?lat=31.3260152&lng=75.57618289999999&is-seo-homepage-enabled=true&page_type=DESKTOP_WEB_LISTING" ); const json = await data.json(); // 使用可选链避免路径不存在的错误,正确获取餐厅数组 const restaurants = json.data?.cards[5]?.card?.card?.gridElements?.infoWithStyle?.restaurants || []; setListOfRestaurants(restaurants); } catch (error) { console.error("获取餐厅数据失败:", error); setListOfRestaurants([]); } }; return ( <div className="body-container"> <div className="res-container"> {/* 空数组时显示加载提示 */} {listOfRestaurants.length === 0 ? ( <p>加载中...</p> ) : ( listOfRestaurants.map((restaurant) => ( <RestaurantCard key={restaurant.info.id} resData={restaurant} /> )) )} </div> </div> ); }; export default Body;
- 关键修改:
- 用
|| []保证即使路径错误,listOfRestaurants始终是数组,避免map报错 - 添加
try-catch处理请求失败的情况 - 给
RestaurantCard添加唯一key(React列表渲染要求) - 增加加载状态提示提升用户体验
- 用
2. 修正RestaurantCard.js
import { CDN_URL } from "./utils/constants"; const RestaurantCard = ({ resData }) => { // 从单个餐厅对象的info属性中解构所需字段 const { name, cuisines, costForTwo, avgRating, deliveryTime, cloudinaryImageId } = resData.info || {}; return ( <div className="res-card"> <div className="res-logo"> <img src={`${CDN_URL}${cloudinaryImageId}`} alt={name || "餐厅图片"} /> </div> <h4>{name || "未知餐厅"}</h4> <p>{cuisines?.join(", ") || "暂无菜系信息"}</p> <p>{costForTwo || "暂无价格信息"}</p> <p>{avgRating || "暂无评分"} ⭐</p> <p>{deliveryTime || "暂无配送时间"} Mins. ⏰</p> </div> ); }; export default RestaurantCard;
- 关键修改:
- 直接解构
resData.info中的字段,简化数据访问 - 使用
||处理字段不存在的情况,避免渲染错误 - 修正图片URL拼接方式,修复原代码中
restaurants未定义的错误 - 用对象解构简化props接收逻辑
- 直接解构
额外注意事项
- Swiggy的API结构可能随时变化,硬编码
cards[5]存在维护风险,建议通过遍历卡片找到包含餐厅列表的卡片(比如判断卡片类型) - 开发时可以通过
console.log(json)查看最新的API返回结构,确保路径正确
内容的提问来源于stack exchange,提问作者Gagan Cheema
相关产品推荐
相关产品推荐

