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

React JS如何实现点击按钮添加同组件行、点击删除按钮移除对应行

React 动态增删表行实现方案

核心逻辑是用数组状态存储所有行的表单数据,通过操作数组实现行的新增和删除,不需要复杂的第三方依赖。

前置准备

如果用的是MUI组件库,先确保你已经安装了对应的依赖,用其他组件库也可以直接套用逻辑。

完整实现步骤

1. 初始化状态

定义数组状态存储每行数据,初始默认渲染一行空白表单:

import { useState } from 'react';
// 以下是MUI组件示例,可替换为你项目里的对应控件
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import TextField from '@mui/material/TextField';
import TextareaAutosize from '@mui/material/TextareaAutosize';
import Button from '@mui/material/Button';

export default function DynamicForm() {
  // 定义单行的初始字段,可根据业务需求增减
  const initRowData = {
    select: '',
    input: '',
    textarea: ''
  };
  const [formRows, setFormRows] = useState([initRowData]);

2. 新增行逻辑

点击新增按钮时往数组末尾追加一条空白行数据即可:

const handleAddRow = () => {
  setFormRows([...formRows, {...initRowData}]);
};

3. 删除行逻辑

点击删除按钮时过滤掉对应索引的行数据:

const handleDeleteRow = (targetIndex) => {
  setFormRows(formRows.filter((_, index) => index !== targetIndex));
};

4. 表单值同步逻辑

修改某行的控件值时,同步更新数组中对应位置的字段:

const handleFieldChange = (rowIndex, fieldName, value) => {
  const updatedRows = [...formRows];
  updatedRows[rowIndex][fieldName] = value;
  setFormRows(updatedRows);
};

5. 渲染表单行

遍历数组渲染所有行,仅在最后一行显示新增按钮,其他行显示删除按钮:

return (
    <div style={{ padding: '20px', maxWidth: '800px' }}>
      {formRows.map((row, index) => (
        <div 
          key={index} 
          style={{ display: 'flex', gap: '12px', marginBottom: '16px', alignItems: 'flex-start' }}
        >
          {/* 下拉选择控件 */}
          <Select
            value={row.select}
            onChange={(e) => handleFieldChange(index, 'select', e.target.value)}
            style={{ minWidth: '140px' }}
          >
            <MenuItem value="option1">选项1</MenuItem>
            <MenuItem value="option2">选项2</MenuItem>
            <MenuItem value="option3">选项3</MenuItem>
          </Select>

          {/* 单行输入框 */}
          <TextField
            value={row.input}
            onChange={(e) => handleFieldChange(index, 'input', e.target.value)}
            placeholder="请输入内容"
          />

          {/* 多行文本框 */}
          <TextareaAutosize
            value={row.textarea}
            onChange={(e) => handleFieldChange(index, 'textarea', e.target.value)}
            minRows={2}
            placeholder="请输入多行内容"
            style={{ width: '280px', padding: '8px' }}
          />

          {/* 操作按钮:最后一行显新增,其他显删除 */}
          {index === formRows.length - 1 ? (
            <Button variant="contained" onClick={handleAddRow}>
              新增行
            </Button>
          ) : (
            <Button variant="outlined" color="error" onClick={() => handleDeleteRow(index)}>
              删除
            </Button>
          )}
        </div>
      ))}
    </div>
  );
}

注意事项

  • 示例中用数组索引作为key是简化写法,如果你的业务数据有唯一ID,建议替换为唯一ID,避免列表更新时出现渲染异常
  • 表单字段的校验、提交逻辑可以根据业务需求自行扩展,核心的数组操作逻辑不需要修改
  • 如果你用的不是MUI组件库,直接把对应控件替换成你项目里的下拉、输入框、多行文本组件即可,逻辑完全通用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:48:02