如何为MUI Table实现类MS Word添加行功能并关联react-hook-form?
MUI Table实现Word式插入行 + react-hook-form关联方案
一、技术选型:直接用MUI就行,别从零写
MUI的Table组件自带成熟的样式体系和交互基础,完全能实现这个需求。从零用原生HTML写的话,你得自己处理悬停样式、按钮对齐、和现有项目UI风格统一这些琐碎事,纯纯浪费时间。用MUI能直接复用现成组件,效率高多了。
二、核心实现步骤
1. 基础框架:MUI Table + react-hook-form FieldArray
先用MUI的Table系列组件搭好表格结构,再用react-hook-form的useFieldArray管理行数据——这玩意儿专门用来处理表单里的动态数组,插入、删除、修改都能自动同步表单状态,省得自己写状态逻辑。
2. 悬停显示加号按钮
给每个TableRow加onMouseEnter和onMouseLeave事件,记录当前悬停的行索引。然后在每行的最左侧放个MUI的IconButton(用Add图标),默认隐藏,只有当该行处于悬停状态时才显示。
3. 点击插入行
点击加号时,调用useFieldArray的insert方法,在当前行的位置(比如下方)插入一条空数据就行,表单状态会自动更新。
三、完整代码示例
import { useState } from 'react'; import { useForm, useFieldArray } from 'react-hook-form'; import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, IconButton, Add } from '@mui/material'; export default function InsertRowTable() { const { control, register } = useForm({ defaultValues: { rows: [ { id: 1, name: '默认行1', value: '示例值1' }, { id: 2, name: '默认行2', value: '示例值2' }, ], }, }); const { fields, insert } = useFieldArray({ control, name: 'rows', }); const [hoveredIndex, setHoveredIndex] = useState(null); const handleInsert = (index) => { // 在当前行下方插入新行,要插上方直接传index就行 insert(index + 1, { id: Date.now(), name: '', value: '' }); }; return ( <TableContainer component={Paper}> <Table> <TableHead> <TableRow> <TableCell sx={{ width: 40 }}></TableCell> <TableCell>名称</TableCell> <TableCell>值</TableCell> </TableRow> </TableHead> <TableBody> {fields.map((row, index) => ( <TableRow key={row.id} onMouseEnter={() => setHoveredIndex(index)} onMouseLeave={() => setHoveredIndex(null)} > <TableCell> {hoveredIndex === index && ( <IconButton size="small" onClick={() => handleInsert(index)} sx={{ opacity: 0.7, transition: 'opacity 0.2s', '&:hover': { opacity: 1 } }} > <Add /> </IconButton> )} </TableCell> <TableCell> <input {...register(`rows.${index}.name`)} style={{ width: '100%', padding: '4px', border: '1px solid #eee', borderRadius: '4px' }} /> </TableCell> <TableCell> <input {...register(`rows.${index}.value`)} style={{ width: '100%', padding: '4px', border: '1px solid #eee', borderRadius: '4px' }} /> </TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> ); }
关键细节说明
hoveredIndex用来跟踪当前悬停的行,控制加号按钮的显隐useFieldArray的insert方法直接操作表单数组,不用手动维护状态- MUI的
IconButton自带点击反馈和样式,加个过渡动画让显示/隐藏更丝滑
四、优化小技巧
- 插入新行后可以自动聚焦到第一个输入框,用
useEffect或者ref实现 - 表格行数多的话,给
TableRow套个React.memo减少不必要的渲染 - 可以把加号按钮的位置调整到行的右侧,或者根据你的UI需求自定义样式
内容的提问来源于stack exchange,提问作者Ákos Dániel Bollók
相关产品推荐
相关产品推荐

