如何独立控制MUI表格每行单元格中的下拉选择框?
解决Material UI表格每行下拉框独立控制的问题
问题根源
你当前用单个access状态变量控制所有行的下拉框值,所以修改任意一行的选项时,所有行都会同步变化。要实现独立控制,需要为每行维护单独的状态。
修复步骤及代码
- 初始化状态为对象,记录每行的权限值,默认给所有行设为
1(对应Allow选项) - 修改
handleChange方法,通过行的唯一标识(比如name)更新对应行的权限 - 渲染下拉框时,绑定当前行对应的状态值
修改后的完整代码:
import * as React from "react"; import { Select, MenuItem, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper } from "@mui/material"; import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; function createData(name, mobile, access) { return { name, mobile, access }; } const rows = [ createData("Sam", 9865745159), createData("Amily", 8723879237), createData("Eva", 9432671262), createData("Jack", 7898083305), createData("Diana", 8973667356) ]; export default function DenseTable() { // 初始化状态为对象,key是行的name,value是权限值,默认都为1 const [accessState, setAccessState] = React.useState( rows.reduce((acc, row) => ({ ...acc, [row.name]: 1 }), {}) ); const handleChange = (event, row) => { // 更新对应行的权限值 setAccessState(prev => ({ ...prev, [row.name]: event.target.value })); }; return ( <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} size="small" aria-label="a dense table"> <TableHead> <TableRow> <TableCell align="center">Name</TableCell> <TableCell align="center">Mobile</TableCell> <TableCell align="center">Access</TableCell> </TableRow> </TableHead> <TableBody> {rows.map((row) => ( <TableRow key={row.name} sx={{ "&:last-child td, &:last-child th": { border: 0 } }} > <TableCell component="th" scope="row" align="center"> {row.name} </TableCell> <TableCell align="center">{row.mobile}</TableCell> <TableCell align="center"> <Select // 绑定当前行对应的状态值 value={accessState[row.name]} // 传递当前行数据到回调 onChange={(e) => handleChange(e, row)} MenuProps={{ MenuListProps: { disablePadding: true } }} fullWidth size="small" IconComponent={() => ( <KeyboardArrowDownIcon sx={{ position: "absolute", right: 10, width: "20px", pointerEvents: "none" }} /> )} sx={{ fontSize: "14px", width: "100px", height: "28px" }} > <MenuItem value={1} sx={{ fontSize: "14px", height: "25px", width: "100%" }} > Allow </MenuItem> <MenuItem value={2} sx={{ fontSize: "14px", height: "30px", width: "100%" }} > Decline </MenuItem> </Select> </TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> ); }
关键改动说明
- 状态结构调整:从单个值改为对象,以每行的
name作为唯一键,确保每行的权限值独立存储 - 回调函数优化:在
onChange中传递当前行数据,更新时只修改对应行的状态 - 值绑定调整:下拉框的
value不再绑定全局的access,而是取当前行对应的accessState[row.name]
内容的提问来源于stack exchange,提问作者Aparajita
相关产品推荐
相关产品推荐

