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
相关产品推荐
相关产品推荐

