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

如何独立控制MUI表格每行单元格中的下拉选择框?

解决Material UI表格每行下拉框独立控制的问题

问题根源

你当前用单个access状态变量控制所有行的下拉框值,所以修改任意一行的选项时,所有行都会同步变化。要实现独立控制,需要为每行维护单独的状态。

修复步骤及代码

  1. 初始化状态为对象,记录每行的权限值,默认给所有行设为1(对应Allow选项)
  2. 修改handleChange方法,通过行的唯一标识(比如name)更新对应行的权限
  3. 渲染下拉框时,绑定当前行对应的状态值

修改后的完整代码:

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:01:22