React中fetch请求数据存入useState后如何正常渲染展示
问题原因
- 接口返回的
itemDetails是包含item、customerList两个属性的对象,而非数组,你直接对对象调用数组的map方法,自然会触发itemDetails.map is not a function报错 - 初始状态设置和实际存储结构不匹配,你初始值设为
[]空数组,和后续存入的对象结构不一致,第一次渲染阶段就存在取值异常的隐患 - 遍历目标和取值路径错误:你需要循环渲染的是
itemDetails下的customerList数组,而非整个itemDetails对象;同时遍历到单条客户数据后,直接取对应字段即可,不需要再嵌套customerList层级
修复步骤
- 调整状态初始值,匹配接口返回的结构,避免空值报错
- 商品基础信息直接从
itemDetails.item中取对应字段渲染 - 表格部分改为遍历
itemDetails.customerList数组渲染客户数据 - 增加可选链语法,避免数据未请求完成时的空值报错,同时给遍历生成的节点补充唯一key属性消除React警告
修正后完整代码
function ItemDetails() { //variable to store data passes from handlePageChange const location = useLocation(); const itemID = location.state.itemID; const year = location.state.year; // 修正初始值结构,匹配返回数据格式 const [itemDetails, setItemDetails] = useState({ item: {}, customerList: [] }); console.log(itemDetails); useEffect(() => { const fetchItemDetails = async () => { if(year != null && itemID != null){ try { const response = await fetch(`http://localhost:56384/api/RecallDetail?itemID=${itemID}&year=${year}`); setItemDetails(await response.json()); } catch (error) { console.log('Failed to fetch from Amazon DB', error); } } else { try { const response = await fetch(`http://localhost:56384/api/RecallDetail?itemID=${itemID}`); setItemDetails(await response.json()); } catch (error) { console.log('Failed to fetch from Amazon DB', error); } } }; fetchItemDetails(); }, []); return ( <div> <div> <h1>Recall Information</h1> {/* 修正商品信息取值路径,从item属性取 */} <p>Product: {itemDetails.item?.itemName}</p> <p>Unit Cost: {itemDetails.item?.itemCost}</p> <p>Description: {itemDetails.item?.itemDescription}</p> </div> <div> <table> <thead> <tr> <th>Customer Name</th> <th>Contact Details</th> <th>Addrress Line</th> <th>Total Cost</th> <th>Units Sold</th> </tr> </thead> <tbody> {/* 修正遍历目标为customerList数组,用可选链避免空值报错,补充key属性 */} {itemDetails.customerList?.map(customer => { return ( <tr key={customer.email}> {/* 直接取当前遍历到的customer对象的属性 */} <td>{ customer.customerName }</td> <td>{ customer.email }</td> <td>{ customer.addressLine1 }</td> <td>${ customer.totalCost }</td> <td>{ customer.unitsSold}</td> </tr> ); })} </tbody> </table> </div> <NavLink to="/" activeClassName="active"> Go Back </NavLink> </div> ); }
内容的提问来源于stack exchange,提问作者Jesse Ly
相关产品推荐
相关产品推荐

