React异步函数中array.push失效问题求助
问题原因与解决方案
问题原因
核心是异步操作的执行顺序问题:
你在items.map中调用的getPack是异步函数,每次调用都会返回一个Promise,但代码里没有等待这些异步请求完成,就直接执行了setCart(array)和console.log(array)。此时所有array.push(result.data)的操作都还没触发(因为API请求还在进行中),所以array是空的,最终setCart也设置了空数组。
解决方案
正确写法(使用Promise.all并行处理请求)
const [cart, setCart] = useState([]) // 初始值改为数组,匹配后续存储的数据类型 useEffect(() => { // 封装异步逻辑到单独函数中(useEffect回调不能直接是async函数) const fetchCartItems = async () => { const items = JSON.parse(localStorage.getItem('cart')); if (items && items.length) { // 用Promise.all等待所有API请求完成,统一获取结果 const cartItems = await Promise.all( items.map(cartId => getPack(cartId).then(res => res.data)) ); setCart(cartItems); console.log(cartItems); // 此时能拿到完整的购物车数据 } }; fetchCartItems(); }, []); const getPack = async(id) => { return await Api.Get('getPack', false, false, id); }
关键修改点说明
- 调整初始状态:把
useState({})改为useState([]),因为你要存储的是数组类型的购物车数据,对象初始值不符合业务逻辑。 - 异步逻辑封装:将useEffect中的异步代码封装到单独的
async函数里,避免useEffect直接返回Promise引发React警告。 - 用
Promise.all处理并行请求:Promise.all会等待所有传入的API请求Promise都完成后,返回一个包含所有结果的数组,确保你在调用setCart时已经拿到了所有数据。
备选方案(串行处理请求,适合需要顺序调用的场景)
如果需要按顺序发起API请求(而非并行),可以用for...of循环配合await:
useEffect(() => { const fetchCartItems = async () => { const items = JSON.parse(localStorage.getItem('cart')); if (items && items.length) { const cartItems = []; for (const cartId of items) { const res = await getPack(cartId); cartItems.push(res.data); } setCart(cartItems); } }; fetchCartItems(); }, []);
内容的提问来源于stack exchange,提问作者Jack The Baker
相关产品推荐
相关产品推荐

