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

Material UI DataGrid仅传递表格最后一行数据至模态框问题求助

解决Material UI DataGrid行操作菜单传递当前行数据总是最后一行的问题

这个问题是典型的闭包陷阱导致的:如果你在renderCell中用外部变量存储当前行数据(比如let currentRow; currentRow = params.row),所有行的点击事件都会共享这个变量的引用,表格渲染完成后变量会被最后一行的数据覆盖,最终点击任何行都只会拿到最后一行的数据。

正确处理方式

不需要依赖外部变量,直接在点击事件中绑定当前行的params.row,并更新模态框的状态:

基础实现示例

import { useState } from 'react';
import { DataGrid, IconButton } from '@mui/x-data-grid';
import { MoreVertIcon } from '@mui/icons-material';
import Modal from '@mui/material/Modal';

export default function UserTable({ users }) {
  const [selectedUser, setSelectedUser] = useState(null);
  const [isModalOpen, setIsModalOpen] = useState(false);

  const columns = [
    { field: 'id', headerName: 'ID', width: 70 },
    { field: 'name', headerName: '姓名', width: 130 },
    { field: 'email', headerName: '邮箱', width: 200 },
    // 操作列
    {
      field: 'actions',
      headerName: '操作',
      width: 150,
      renderCell: (params) => (
        <IconButton
          onClick={() => {
            // 直接将当前行数据传入状态更新
            setSelectedUser(params.row);
            setIsModalOpen(true);
          }}
          size="small"
        >
          <MoreVertIcon />
        </IconButton>
      ),
    },
  ];

  return (
    <>
      <DataGrid
        rows={users}
        columns={columns}
        rowKey="id"
        autoHeight
      />
      {/* 模态框 */}
      <Modal
        open={isModalOpen}
        onClose={() => setIsModalOpen(false)}
        aria-labelledby="user-detail-modal"
      >
        <div style={{ padding: 20, margin: '10% auto', backgroundColor: 'white', maxWidth: 400 }}>
          <h2 id="user-detail-modal">用户详情</h2>
          {selectedUser && (
            <div>
              <p>ID: {selectedUser.id}</p>
              <p>姓名: {selectedUser.name}</p>
              <p>邮箱: {selectedUser.email}</p>
            </div>
          )}
        </div>
      </Modal>
    </>
  );
}

封装点击函数的写法

如果需要将打开模态框的逻辑封装成单独函数,直接给函数传递当前行数据即可:

const handleOpenModal = (rowData) => {
  setSelectedUser(rowData);
  setIsModalOpen(true);
};

// 操作列的renderCell修改为:
renderCell: (params) => (
  <IconButton onClick={() => handleOpenModal(params.row)} size="small">
    <MoreVertIcon />
  </IconButton>
)

关于重载错误的说明

你提到用userData替代params出现重载错误,是因为DataGrid的renderCell函数要求参数必须是GridRenderCellParams类型(包含当前行、列等上下文信息),不能随意替换变量名。正确的做法是通过params.row获取当前行的数据,而不是替换params本身。

内容的提问来源于stack exchange,提问作者Mike Nito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:20:38