如何在MUI DataGrid中实现单元格内容变更时同步更新状态?
MUI DataGrid 5+ 实现单元格输入实时更新状态
在MUI DataGrid 5+版本中,需要实现单元格输入内容时实时触发状态更新,而非依赖onCellEditCommit仅在点击组件外部、按Tab/Enter键时才保存。同时要配合useEffect监听状态变化,控制“保存”“取消”按钮的启用/禁用。
解决方案一:用onEditCellChange事件实时更新
onEditCellChange会在单元格编辑值发生变化时立即触发,无需等待提交操作。直接替换原有事件并调整状态更新逻辑即可:
... import { DataGrid, GridColDef, GridEditCellParams, } from "@mui/x-data-grid"; ... const [devices, setDevices] = useState<Device[]>(formValues.devices); // 实时更新单元格数据的函数 function updateDeviceCell(params: GridEditCellParams) { // 使用函数式更新避免 stale state 问题 setDevices(prevDevices => { return prevDevices.map(device => { if (device.id === params.id) { return { ...device, [params.field]: params.value }; } return device; }); }); } ... return ( <DataGrid rows={devices} columns={columns} hideFooterPagination hideFooter disableSelectionOnClick autoHeight onEditCellChange={updateDeviceCell} // 替换原有的onCellEditCommit editMode="cell" /> ... );
关键说明
onEditCellChange在用户每一次输入(键盘打字、复选框切换)时都会触发,完美实现实时更新- 函数式更新
setDevices(prev => ...)比直接复制旧数组更可靠,能避免闭包导致的状态过期问题
解决方案二:自定义编辑组件(更灵活)
如果需要对输入行为做精细控制(比如实时校验、格式化输入),可以给可编辑列指定自定义editComponent,在组件的onChange中直接更新状态:
// 自定义文本输入组件 const CustomTextField = (props) => { const { id, field, value, api } = props; const handleChange = (event) => { const newValue = event.target.value; // 更新本地状态 setDevices(prev => prev.map(dev => dev.id === id ? {...dev, [field]: newValue} : dev )); // 通知DataGrid同步编辑状态,避免UI显示不一致 api.setEditCellValue({ id, field, value: newValue }); }; return <TextField value={value} onChange={handleChange} fullWidth />; }; // 自定义布尔值复选框组件 const CustomCheckbox = (props) => { const { id, field, value } = props; const handleChange = (event) => { const newValue = event.target.checked; setDevices(prev => prev.map(dev => dev.id === id ? {...dev, [field]: newValue} : dev )); }; return <Checkbox checked={value} onChange={handleChange} />; }; // 修改列定义,指定自定义编辑组件 const columns: GridColDef[] = [ { field: "id", headerName: "ID", flex: 10, }, { field: "uniqueIdentification", headerName: "Unique ID", editable: true, flex: 30, editComponent: CustomTextField, }, { field: "description", headerName: "Description", editable: true, flex: 50, editComponent: CustomTextField, }, { field: "isActive", headerName: "Active", type: "boolean", editable: true, flex: 10, editComponent: CustomCheckbox, }, // ...操作列保持不变 ];
关键说明
- 这种方式完全掌控输入组件的交互逻辑,适合有额外业务需求的场景
- 调用
api.setEditCellValue可以让DataGrid内部的编辑状态和本地状态保持同步,避免UI显示异常
无论使用哪种方案,useEffect都能实时监听到devices状态的变化,从而正确控制“保存”“取消”按钮的启用/禁用。
内容的提问来源于stack exchange,提问作者William Zimmermann
相关产品推荐
相关产品推荐

