MUI X DataGrid编辑删除按钮异常:基础版无法进入行编辑模式
MUI DataGrid基础版行编辑不生效的解决方案
问题根源
MUI的DataGrid(基础版)仅支持单元格级编辑,不提供DataGridPro专属的整行编辑模式。你复制的Pro版代码中使用了editMode="row"、rowModesModel等Pro版独有的API,基础版无法识别这些配置,因此点击编辑按钮后仅切换了操作按钮,单元格并未进入编辑状态。
两种解决方案
方案1:改用DataGridPro(推荐,若项目允许)
如果你的项目可以引入Pro版依赖,直接将DataGrid换回DataGridPro,现有代码就能正常运行,无需额外修改。
方案2:基于DataGrid基础版实现模拟行编辑
如果必须使用基础版,需要手动控制单元格的编辑状态,模拟整行编辑的效果。以下是修改后的代码:
import * as React from "react"; import PropTypes from "prop-types"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; import AddIcon from "@mui/icons-material/Add"; import EditIcon from "@mui/icons-material/Edit"; import DeleteIcon from "@mui/icons-material/DeleteOutlined"; import SaveIcon from "@mui/icons-material/Save"; import CancelIcon from "@mui/icons-material/Close"; import { GridCellModes, DataGrid, GridToolbarContainer, GridActionsCellItem, } from "@mui/x-data-grid"; import { randomCreatedDate, randomTraderName, randomUpdatedDate, randomId, } from "@mui/x-data-grid-generator"; const initialRows = [ { id: randomId(), name: randomTraderName(), age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: randomId(), name: randomTraderName(), age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: randomId(), name: randomTraderName(), age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: randomId(), name: randomTraderName(), age: 28, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: randomId(), name: randomTraderName(), age: 23, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, ]; function EditToolbar(props) { const { setRows, setCellModesModel } = props; const handleClick = () => { const id = randomId(); const newRow = { id, name: "", age: "", dateCreated: new Date(), lastLogin: new Date(), isNew: true }; setRows((oldRows) => [...oldRows, newRow]); // 新行直接进入编辑状态 const cellModes = {}; ["name", "age", "dateCreated", "lastLogin"].forEach(field => { cellModes[`${id}-${field}`] = { mode: GridCellModes.Edit }; }); setCellModesModel(prev => ({ ...prev, ...cellModes })); }; return ( <GridToolbarContainer> <Button color="primary" startIcon={<AddIcon />} onClick={handleClick}> Add record </Button> </GridToolbarContainer> ); } EditToolbar.propTypes = { setCellModesModel: PropTypes.func.isRequired, setRows: PropTypes.func.isRequired, }; export default function FullFeaturedCrudGrid() { const [rows, setRows] = React.useState(initialRows); const [cellModesModel, setCellModesModel] = React.useState({}); const handleEditClick = (id) => () => { // 将该行所有可编辑字段设为编辑状态 const newCellModes = {}; ["name", "age", "dateCreated", "lastLogin"].forEach(field => { newCellModes[`${id}-${field}`] = { mode: GridCellModes.Edit }; }); setCellModesModel(prev => ({ ...prev, ...newCellModes })); }; const handleSaveClick = (id) => () => { // 将该行所有字段设为查看状态 const newCellModes = {}; ["name", "age", "dateCreated", "lastLogin"].forEach(field => { newCellModes[`${id}-${field}`] = { mode: GridCellModes.View }; }); setCellModesModel(prev => ({ ...prev, ...newCellModes })); // 标记新行已保存 setRows(prev => prev.map(row => row.id === id ? { ...row, isNew: false } : row )); }; const handleDeleteClick = (id) => () => { setRows(rows.filter((row) => row.id !== id)); // 清除该行的编辑状态记录 const newCellModes = { ...cellModesModel }; ["name", "age", "dateCreated", "lastLogin"].forEach(field => { delete newCellModes[`${id}-${field}`]; }); setCellModesModel(newCellModes); }; const handleCancelClick = (id) => () => { // 将该行所有字段设为查看状态 const newCellModes = {}; ["name", "age", "dateCreated", "lastLogin"].forEach(field => { newCellModes[`${id}-${field}`] = { mode: GridCellModes.View, ignoreModifications: true }; }); setCellModesModel(prev => ({ ...prev, ...newCellModes })); // 删除未保存的新行 const editedRow = rows.find((row) => row.id === id); if (editedRow.isNew) { setRows(rows.filter((row) => row.id !== id)); } }; const processRowUpdate = (newRow) => { const updatedRow = { ...newRow, isNew: false }; setRows(rows.map((row) => (row.id === newRow.id ? updatedRow : row))); return updatedRow; }; const columns = [ { field: "name", headerName: "Name", width: 180, editable: true }, { field: "age", headerName: "Age", type: "number", editable: true }, { field: "dateCreated", headerName: "Date Created", type: "date", width: 180, editable: true, }, { field: "lastLogin", headerName: "Last Login", type: "dateTime", width: 220, editable: true, }, { field: "actions", type: "actions", headerName: "Actions", width: 100, cellClassName: "actions", getActions: ({ id }) => { // 判断该行是否有任意单元格处于编辑状态 const isInEditMode = ["name", "age", "dateCreated", "lastLogin"].some(field => cellModesModel[`${id}-${field}`]?.mode === GridCellModes.Edit ); if (isInEditMode) { return [ <GridActionsCellItem icon={<SaveIcon />} label="Save" onClick={handleSaveClick(id)} />, <GridActionsCellItem icon={<CancelIcon />} label="Cancel" className="textPrimary" onClick={handleCancelClick(id)} color="inherit" />, ]; } return [ <GridActionsCellItem icon={<EditIcon />} label="Edit" className="textPrimary" onClick={handleEditClick(id)} color="inherit" />, <GridActionsCellItem icon={<DeleteIcon />} label="Delete" onClick={handleDeleteClick(id)} color="inherit" />, ]; }, }, ]; return ( <Box sx={{ height: 500, width: "100%", "& .actions": { color: "text.secondary", }, "& .textPrimary": { color: "text.primary", }, }} > <DataGrid rows={rows} columns={columns} cellModesModel={cellModesModel} onCellModesModelChange={(newModel) => setCellModesModel(newModel)} processRowUpdate={processRowUpdate} slots={{ toolbar: EditToolbar, }} slotProps={{ toolbar: { setRows, setCellModesModel }, }} /> </Box> ); }
关键修改说明
- 移除了
editMode="row"、rowModesModel等Pro版专属属性,改用基础版支持的cellModesModel控制单个单元格的编辑状态 - 点击编辑按钮时,批量将该行所有可编辑字段设为编辑模式
- 通过判断该行任意单元格的编辑状态,切换操作按钮的显示
- 调整新增行的逻辑,直接将新行的所有可编辑字段设为编辑状态
内容的提问来源于stack exchange,提问作者jm2002
相关产品推荐
相关产品推荐

