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
相关产品推荐
相关产品推荐

