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

MUI Datagrid:如何通过rowClick事件打开模态框?

解决方案

一、模态框的放置位置

ChildModal#2需要放在AddItem组件内部,因为它的显示状态需要被AddItem里的handleRowClick控制,同时要保证它处于React的DOM树范围内(主流UI库的模态框通常会通过Portal挂载到body,但组件结构上要放在能访问控制状态的组件层级里)。

二、如何在onRowClick中调用模态框

核心思路是把模态框的显示状态(open)和控制逻辑提到AddItem组件中,让handleRowClick可以直接修改状态打开模态框,同时把选中的行数据传递给模态框,用于后续添加到表格#1的操作。

修改后的完整代码示例

// 子模态框组件:接收控制状态、选中数据、添加回调
function ChildModal2({ open, handleClose, selectedRow, onAddSuccess }) {
  // 处理确认添加逻辑
  const handleConfirm = () => {
    onAddSuccess(selectedRow); // 把选中数据回传给父组件
    handleClose();
  };

  return (
    <Modal open={open} onClose={handleClose}>
      <Box padding={2}>
        <Typography variant="h6">确认添加到表格#1</Typography>
        <Typography>型号: {selectedRow.STOCKCODE}</Typography>
        <Typography>描述: {selectedRow.DESC}</Typography>
        <Box marginTop={2} display="flex" gap={1} justifyContent="flex-end">
          <Button onClick={handleClose}>取消</Button>
          <Button onClick={handleConfirm} variant="contained">确认添加</Button>
        </Box>
      </Box>
    </Modal>
  );
}

function AddItem({ onAddToTable1 }) {
  const [openTable2Modal, setOpenTable2Modal] = React.useState(false);
  const [openChildModal2, setOpenChildModal2] = React.useState(false);
  const [selectedRow, setSelectedRow] = React.useState(null);
  const [message, setMessage] = React.useState('');

  // 控制表格#2模态框的显示/隐藏
  const handleOpenTable2Modal = () => setOpenTable2Modal(true);
  const handleCloseTable2Modal = () => setOpenTable2Modal(false);

  // 表格#2行点击事件:保存选中行并打开子模态框
  const handleRowClick = (params) => {
    const rowData = params.row;
    setSelectedRow(rowData);
    setMessage(`已选择型号 \"${rowData.STOCKCODE} - ${rowData.DESC}\"`);
    setOpenChildModal2(true); // 直接触发子模态框打开
  };

  return (
    <div>
      <Box onClick={handleOpenTable2Modal} sx={{ cursor: 'pointer' }}>添加 Item</Box>
      
      {/* 表格#2的模态框 */}
      <Modal open={openTable2Modal} onClose={handleCloseTable2Modal}>
        <Box padding={3}>
          <Typography variant="h5">源数据表格</Typography>
          <DataGrid
            onRowClick={handleRowClick}
            // 其他表格配置项...
          />
        </Box>
      </Modal>

      {/* ChildModal2 放在AddItem内部,直接受当前组件状态控制 */}
      <ChildModal2
        open={openChildModal2}
        handleClose={() => setOpenChildModal2(false)}
        selectedRow={selectedRow}
        onAddSuccess={onAddToTable1}
      />
    </div>
  );
}

// 主组件
export default function ModalCatalog() {
  const [openMainModal, setOpenMainModal] = React.useState(false);
  const [table1Data, setTable1Data] = React.useState([]); // 表格#1的数据源

  // 接收新增数据并更新表格#1
  const handleAddToTable1 = (newRow) => {
    setTable1Data(prev => [...prev, newRow]);
  };

  return (
    <section>
      <Button onClick={() => setOpenMainModal(true)}>打开主模态框</Button>
      
      {/* 主模态框 */}
      <Modal open={openMainModal} onClose={() => setOpenMainModal(false)}>
        <Box padding={3}>
          <Fab>
            <AddItem onAddToTable1={handleAddToTable1} /> {/* 传递添加回调 */}
          </Fab>
          <GridCatalog data={table1Data} /> {/* 表格#1接收更新后的数据 */}
        </Box>
      </Modal>
    </section>
  );
}

关键说明

  • 状态上移:将ChildModal2的显示状态放到AddItem组件中,让handleRowClick可以直接修改状态打开模态框。
  • 数据传递:通过props把选中的行数据传给ChildModal2,同时传递onAddSuccess回调,在用户确认添加时将数据回传给ModalCatalog,更新表格#1的数据源。
  • 层级兼容:主流UI库的Modal组件会自动通过Portal挂载到DOM顶层,不会被父级模态框遮挡,无需额外处理层级问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:55:13