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

React中如何动态向state添加嵌套对象更新commission数组

实现方案

你当前代码存在两个核心问题:一是Form.List的name字段拼写错误(写为commision,和state中定义的commission不匹配);二是动态表单项的值用了自定义拼接的平铺key存储,没有和commission数组结构做映射,所以无法生成你需要的数组格式。
按以下步骤调整即可:

1. 修正基础state定义

先补全初始state的语法闭合,保证结构正确:

const [data,setData] = useState({
    city: "",
    address: "",
    zipCode: "",
    phoneNum: "",
    commission: [{ commissionFor: "Invocing", commissionPercentage: "40" }],
})

2. 改造表单项更新逻辑,直接操作commission数组

不需要自己拼接dataName${index}这类自定义key,每次输入时直接按索引更新commission数组内的对应对象即可,新增、删除操作也同步维护这个数组:

<Form onFinish={onFinish}>
  {/* 修正name拼写,和state字段保持一致 */}
  <Form.List name="commission">
    {(fields, { add, remove }, { errors }) => (
      <>
        {fields.map((field, index) => (
          {/* 优先用Form.List生成的field.key作为key,避免用index导致的渲染问题 */}
          <Row key={field.key}>
            <Autocomplete
              value={data.commission[index]?.commissionFor || ""}
              onChange={(e) =>
                setData((prev) => {
                  // 浅拷贝数组避免直接修改原state
                  const newList = [...prev.commission]
                  newList[index] = {
                    ...newList[index],
                    commissionFor: e.target.value
                  }
                  return { ...prev, commission: newList }
                })
              }
            />
            <FormControl>
              <InputLabel>Percentage</InputLabel>
              <OutlinedInput
                value={data.commission[index]?.commissionPercentage || ""}
                onChange={(e) =>
                  setData((prev) => {
                    const newList = [...prev.commission]
                    newList[index] = {
                      ...newList[index],
                      commissionPercentage: e.target.value
                    }
                    return { ...prev, commission: newList }
                  })
                }
                startAdornment={
                  <InputAdornment position="start">
                    {insideIcon}
                  </InputAdornment>
                }
                label="Percentage"
              />
            </FormControl>
            {/* 可选:删除项按钮 */}
            <Button onClick={() => {
              remove(index)
              setData(prev => ({
                ...prev,
                commission: prev.commission.filter((_, i) => i !== index)
              }))
            }}>删除</Button>
          </Row>
        ))}
        <Form.Item>
          {/* Add按钮逻辑 */}
          <Button onClick={() => {
            // 同步更新Form.List和本地state
            add({ commissionFor: "", commissionPercentage: "" })
            setData(prev => ({
              ...prev,
              commission: [...prev.commission, { commissionFor: "", commissionPercentage: "" }]
            }))
          }}>Add</Button>
        </Form.Item>
      </>
    )}
  </Form.List>
</Form>

3. 可选优化:抽离重复逻辑

两个输入框的更新逻辑高度相似,可以抽成通用方法减少冗余代码:

const updateCommissionItem = (index, field, value) => {
  setData(prev => {
    const newList = [...prev.commission]
    newList[index] = { ...newList[index], [field]: value }
    return { ...prev, commission: newList }
  })
}

抽离后,两个表单项的onChange可以简化为:

// Autocomplete的onChange
onChange={(e) => updateCommissionItem(index, "commissionFor", e.target.value)}

// 百分比输入框的onChange
onChange={(e) => updateCommissionItem(index, "commissionPercentage", e.target.value)}

调整后,用户每次输入、新增、删除操作都会直接同步更新data.commission数组,最终就能得到你期望的结构。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:06:57