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

React嵌套循环中使用索引更新state时不同对象同索引值同步修改问题求解

问题根源

你目前的productQuantity是一维数组,所有不同preInvoice条目下的同索引商品都共用同一个数组位置的值,所以修改任意一个条目下的第N个商品数量,所有条目下的第N个商品都会同步变更。

解决方案

把productQuantity调整为二维数组,第一层索引对应preInvoice的条目下标,第二层索引对应每个条目下selectedArray的商品下标,和你的渲染结构完全对应即可。

1. 初始化state结构

如果preInvoice是接口获取的数据,拿到数据后同步初始化productQuantity:

// 示例:preInvoice返回后初始化
const initQuantity = (preInvoiceData) => {
  const quantityArr = preInvoiceData.map(invoiceItem => {
    // 每个发票条目下的商品默认数量可以设为0或者对应商品的初始值
    return invoiceItem.selectedArray.map(() => 0)
  })
  setProductQuantity(quantityArr)
}

2. 修改渲染逻辑

输入框取值同时传入外层preInvoice的索引和内层商品的索引,同时修正循环的key值避免React渲染异常:

{preInvoice && preInvoice.map((item, index) => {
  return (
    item.selectedArray.map((items, indexs) => {
      return (
        <tbody key={`${index}-${indexs}`}>
          <tr>
            <td>{indexs + 1}</td>
            <td>
              <p>{items?.productInfo?.productName}</p>
            </td>
            <td>
              <div>
                <input 
                  className="w-full bg-gray-100" 
                  type="number" 
                  value={productQuantity[index][indexs]} 
                  required={true} 
                  onChange={updateFieldChanged(index, indexs)} 
                />
              </div>
            </td>
            {/* 其余列逻辑不变 */}
          </tr>
        </tbody>
      )
    })
  )
})}

3. 修改更新函数

接收两层索引,仅修改对应位置的值:

const updateFieldChanged = (invoiceIndex, productIndex) => e => {
  setProductQuantity(prev => {
    const newQuantity = [...prev]
    // 拷贝当前修改的发票条目下的数量数组,避免直接修改原state
    newQuantity[invoiceIndex] = [...newQuantity[invoiceIndex]]
    newQuantity[invoiceIndex][productIndex] = e.target.value
    return newQuantity
  })
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 03:15:02