React中Patch请求后仅最后一个商品库存渲染更新的问题解决
问题分析与解决方案
你的问题核心在于React状态更新的异步特性:当多个fetch请求的回调同时触发handleUpdateProduce时,每个回调里的produce状态都是更新前的旧值,导致前面的更新被最后一次更新覆盖,最终只有最后一件商品的库存被正确渲染。
修复方案1:使用函数式状态更新
修改handleUpdateProduce,改用React的函数式setState,它会接收当前最新的状态作为参数,确保每次更新都基于最新数据:
function handleUpdateProduce(food) { console.log(food) // 使用函数式更新,基于最新的prevProduce状态修改 setProduce(prevProduce => prevProduce.map(item => item.id === food.id ? food : item ) ) }
这种方式不需要改动原有的fetch循环逻辑,每个回调都会基于上一次更新后的最新状态修改商品列表,避免状态覆盖。
修复方案2:批量更新(更优)
如果购物车商品较多,多次触发状态更新会影响性能,可以用Promise.all等待所有PATCH请求完成后,一次性更新状态:
// 收集所有更新请求的Promise const updateRequests = inventory.map(acc => { const subtractQuantity = acc.produce.quantity - acc.quantity return fetch(`${process.env.REACT_APP_API_URL}/produce/${acc.produce_id}`, { method: "PATCH", headers: {"Content-Type" : "application/json"}, body: JSON.stringify({ quantity: subtractQuantity, }) }) .then(res => res.json()) }) // 等待所有请求完成后统一更新状态 Promise.all(updateRequests) .then(updatedItems => { setProduce(prevProduce => { // 复制原数组避免直接修改状态 const newProduce = [...prevProduce] updatedItems.forEach(updatedItem => { const targetIndex = newProduce.findIndex(item => item.id === updatedItem.id) if (targetIndex !== -1) { newProduce[targetIndex] = updatedItem } }) return newProduce }) }) .catch(error => console.error("库存更新失败:", error))
这种方式只触发一次状态更新,性能更优,同时也能确保所有商品的库存都被正确同步。
内容的提问来源于stack exchange,提问作者taram414
相关产品推荐
相关产品推荐

