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

React中动态生成新增输入字段ID的实现方案问询

解决方案:动态生成输入字段的唯一ID

要实现点击添加按钮时为新增输入字段生成唯一ID,这里提供两种实用方案,适配不同场景需求:

方案一:利用map索引快速实现

直接借助map循环的索引值拼接ID,这是最简单的实现方式,适合仅需新增行、无删除操作的场景:

{Array.from(Array(counter)).map((_, index) => (
  <div className="row" key={index}>
    <div className="col-sm-2">
      <Box sx={{ minWidth: 120 }}>
        <FormControl fullWidth>
          <InputLabel id={`sales-type-label-${index}`}>Sales Type</InputLabel>
          <Select
            labelId={`sales-type-label-${index}`}
            id={`sales-type-select-${index}`}
            label="Sales Type"
            sx={{ minHeight: 40 }}
            onChange={(e) => handleOnChange(e, index)}
          >
            <MenuItem value="1">Product</MenuItem>
            <MenuItem value="2">Company Sales</MenuItem>
            <MenuItem value="3">Custom Service</MenuItem>
          </Select>
        </FormControl>
      </Box>
    </div>
    <div className="col-sm-2">
      <Box sx={{ minWidth: 120 }}>
        <FormControl fullWidth>
          <TextField
            id={`first-name-input-${index}`}
            label="First Name"
            size="small"
          />
        </FormControl>
      </Box>
    </div>
  </div>
))}

注:如果后续需要支持删除行操作,用索引作为ID可能导致React渲染异常(索引会随行删除重新排序),这时推荐使用方案二。

方案二:使用唯一标识(更健壮)

通过数组存储每一行的表单数据,为每行生成唯一ID(比如用Date.now()或uuid库),适配需要编辑、删除行的复杂场景:

1. 初始化状态与核心函数

import { useState } from 'react';

// 初始化行数据,第一行带唯一ID
const [rows, setRows] = useState([{ id: Date.now(), salesType: '', firstName: '' }]);

// 添加新行
const addRow = () => {
  setRows(prevRows => [...prevRows, { id: Date.now(), salesType: '', firstName: '' }]);
};

// 处理输入值变化
const handleInputChange = (rowId, field, value) => {
  setRows(prevRows => 
    prevRows.map(row => 
      row.id === rowId ? { ...row, [field]: value } : row
    )
  );
};

2. 渲染动态行

{rows.map(row => (
  <div className="row" key={row.id}>
    <div className="col-sm-2">
      <Box sx={{ minWidth: 120 }}>
        <FormControl fullWidth>
          <InputLabel id={`sales-type-label-${row.id}`}>Sales Type</InputLabel>
          <Select
            labelId={`sales-type-label-${row.id}`}
            id={`sales-type-select-${row.id}`}
            label="Sales Type"
            sx={{ minHeight: 40 }}
            value={row.salesType}
            onChange={(e) => handleInputChange(row.id, 'salesType', e.target.value)}
          >
            <MenuItem value="1">Product</MenuItem>
            <MenuItem value="2">Company Sales</MenuItem>
            <MenuItem value="3">Custom Service</MenuItem>
          </Select>
        </FormControl>
      </Box>
    </div>
    <div className="col-sm-2">
      <Box sx={{ minWidth: 120 }}>
        <FormControl fullWidth>
          <TextField
            id={`first-name-input-${row.id}`}
            label="First Name"
            size="small"
            value={row.firstName}
            onChange={(e) => handleInputChange(row.id, 'firstName', e.target.value)}
          />
        </FormControl>
      </Box>
    </div>
    {/* 可选:添加删除按钮 */}
    <button onClick={() => setRows(prev => prev.filter(r => r.id !== row.id))}>删除</button>
  </div>
))}

这种方式不仅能保证ID绝对唯一,还能方便地管理每行的表单数据,适合需要提交多行数据的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 18:35:25