React循环发起GET请求后数组为空,无法传递props的问题
问题解决:异步请求导致数组更新时机错误
问题根源
你遇到的问题是异步请求的执行顺序导致的:forEach循环里的每个axios.get都是异步操作,当你执行console.log和setrelatedProducts时,这些请求还没返回数据,所以relatedProductsInfo还是空数组。但后续请求陆续完成后,数据被push进数组,所以控制台展开时能看到数据,但此时组件已经用空数组完成了初始渲染,不会自动触发更新。
解决方案
使用Promise.all等待所有异步请求完成后,再更新状态。同时要修正useEffect的依赖数组,确保productId变化时重新获取数据。
修改后的代码如下:
// MAIN APP import React, { useState, useEffect } from 'react'; import axios from 'axios'; import OutfitList from './OutfitList.jsx'; import RelatedProductsList from './RelatedProductsList.jsx'; const RelatedItems = ({productId, setproductId, productInfo, setproductInfo}) => { const [relatedProducts, setrelatedProducts] = useState([]); useEffect(() => { GetRelatedProductsList(); }, [productId]) // 加上productId作为依赖,ID变化时重新请求 const GetRelatedProductsList = async () => { // 改成async函数,方便使用await try { const relatedRes = await axios.get(`http://localhost:3001/products/${productId}/related`); const relatedProductIds = relatedRes.data; console.log('related product IDs: ', relatedProductIds); // [37315, 37319] // 把每个ID的请求转换成Promise,用Promise.all等待所有请求完成 const productPromises = relatedProductIds.map(id => axios.get(`http://localhost:3001/products/${id}`) .then(res => res.data) .catch(err => { console.log('failed to retrieve related product info: ', err); return null; // 请求失败时返回null,避免整个Promise.all失败 }) ); const relatedProductsInfo = await Promise.all(productPromises); // 过滤掉请求失败返回的null const validProducts = relatedProductsInfo.filter(item => item !== null); console.log('final related products info: ', validProducts); setrelatedProducts(validProducts); } catch (err) { console.log('failed to retrieve related product IDs: ', err); } } return ( <div> <RelatedProductsList relatedProducts={relatedProducts} setproductId={setproductId}/> </div> ) } export default RelatedItems;
关键修改点
- 用
Promise.all管理异步请求:将每个产品信息的请求包装成Promise,等待所有请求完成后再统一处理结果,确保relatedProductsInfo拿到完整数据后再更新状态。 - 修正
useEffect依赖数组:添加productId作为依赖,当父组件传递的productId变化时,会重新调用GetRelatedProductsList,获取对应产品的关联数据。 - 异常处理优化:单个产品请求失败时返回
null,并在最后过滤掉无效数据,避免影响其他正常请求的结果。
内容的提问来源于stack exchange,提问作者kirasam72
相关产品推荐
相关产品推荐

