You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何更新useState内数组中指定_id的对象

解决React中通过_id更新detail数组对象的问题

你的代码存在两处关键问题,同时需要调整setProducts的调用方式来完成正确的状态更新:

问题1:ID字段匹配错误

你的数据里对象的ID字段是_id,但代码里用了data.id === id,这会导致永远匹配不到目标对象,必须改成data._id === id。

问题2:状态更新的正确姿势

products是包含detail数组的完整状态对象,调用setProducts时要返回完整的新状态对象——保留原对象的其他属性(比如createdAt、discount等),只替换更新后的detail数组。另外推荐使用函数式更新,这种方式能确保拿到最新的状态快照,避免闭包导致的状态不一致问题。

修正后的完整代码

const onChangePriceHandler = (id, e) => {
  const newPrice = Number(e.target.value);
  
  // 过滤无效数字,避免错误更新
  if (isNaN(newPrice)) return;

  // 函数式更新,确保获取最新状态
  setProducts(prevProducts => {
    const updatedDetail = prevProducts.detail?.map(item => {
      if (item._id === id) {
        // 复制原对象,更新采购价和小计
        return {
          ...item,
          purchasePrice: newPrice,
          subtotal: newPrice * item.quantity
        };
      }
      // 非目标对象直接返回原数据
      return item;
    });

    // 返回完整的新状态,保留原对象其他属性
    return {
      ...prevProducts,
      detail: updatedDetail
    };
  });
};

额外优化建议

如果需要同步更新整体total字段(比如基于所有detail的subtotal计算总和并扣除折扣),可以在生成updatedDetail后计算新的total,一并放入新状态中:

const updatedTotal = updatedDetail.reduce((sum, item) => sum + item.subtotal, 0) * (1 - prevProducts.discount / 100);

return {
  ...prevProducts,
  detail: updatedDetail,
  total: updatedTotal
};

内容的提问来源于stack exchange,提问作者OscarDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 22:36:27