DataGrid行内按钮Enable/Disable状态控制问题求助
解决方案:通过React状态管理控制按钮禁用状态
直接操作DOM(比如document.getElementById)在React里不是推荐做法,因为组件渲染由状态驱动,DOM操作会和React虚拟DOM更新冲突。正确方式是用状态跟踪哪些行发生了修改,再根据状态动态控制按钮的禁用状态。
以下是具体实现步骤:
添加状态跟踪修改的行
用useState创建集合记录所有被修改过的行ID,同时把静态rows改成状态,方便后续更新和对比:const [rows, setRows] = useState([ { id: 1, lastName: 'Snow', firstName: 'Jon' }, { id: 2, lastName: 'Lannister', firstName: 'Cersei' }, { id: 3, lastName: 'Lannister', firstName: 'Jaime' }, { id: 4, lastName: 'Stark', firstName: 'Arya' }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys' }, ]); const [modifiedRowIds, setModifiedRowIds] = useState(new Set());更新编辑提交逻辑
在编辑提交时判断值是否真的变化,同步更新modifiedRowIds和表格数据:const handleEditCommit = (params) => { const originalRow = rows.find(row => row.id === params.id); const hasChanged = params.value !== originalRow[params.field]; // 更新修改行标记 setModifiedRowIds(prev => { const newSet = new Set(prev); hasChanged ? newSet.add(params.id) : newSet.delete(params.id); return newSet; }); // 更新表格数据 setRows(prevRows => prevRows.map(row => row.id === params.id ? { ...row, [params.field]: params.value } : row )); };动态控制按钮禁用状态
在renderCell里,根据当前行ID是否在modifiedRowIds中设置按钮状态:{ field: 'button', headerName: '操作', width: 120, renderCell: (cellValues) => ( <button onClick={() => handleButton(cellValues.id)} disabled={!modifiedRowIds.has(cellValues.id)} > 保存 </button> ) }完善按钮点击逻辑
点击保存后移除对应行的修改标记,按钮恢复禁用:const handleButton = (rowId) => { // 替换为实际保存逻辑,比如调用后端API console.log(`保存行 ${rowId} 的数据:`, rows.find(r => r.id === rowId)); // 保存成功后清除修改标记 setModifiedRowIds(prev => { const newSet = new Set(prev); newSet.delete(rowId); return newSet; }); };
完整代码
import { useState } from 'react'; import { DataGrid } from '@mui/x-data-grid'; export default function DataTable() { const [rows, setRows] = useState([ { id: 1, lastName: 'Snow', firstName: 'Jon' }, { id: 2, lastName: 'Lannister', firstName: 'Cersei' }, { id: 3, lastName: 'Lannister', firstName: 'Jaime' }, { id: 4, lastName: 'Stark', firstName: 'Arya' }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys' }, ]); const [modifiedRowIds, setModifiedRowIds] = useState(new Set()); const columns = [ { field: 'id', headerName: 'ID', width: 70 }, { field: 'firstName', headerName: 'First name', editable: true, width: 150 }, { field: 'lastName', headerName: 'Last name', editable: true, width: 150 }, { field: 'button', headerName: '操作', width: 120, renderCell: (cellValues) => ( <button onClick={() => handleButton(cellValues.id)} disabled={!modifiedRowIds.has(cellValues.id)} style={{ padding: '4px 12px', cursor: 'pointer' }} > 保存 </button> ) }, ]; const handleButton = (rowId) => { // 替换为实际保存逻辑 console.log(`保存行 ${rowId} 的数据:`, rows.find(r => r.id === rowId)); setModifiedRowIds(prev => { const newSet = new Set(prev); newSet.delete(rowId); return newSet; }); }; const handleEditCommit = (params) => { const originalRow = rows.find(row => row.id === params.id); const hasChanged = params.value !== originalRow[params.field]; setModifiedRowIds(prev => { const newSet = new Set(prev); hasChanged ? newSet.add(params.id) : newSet.delete(params.id); return newSet; }); setRows(prevRows => prevRows.map(row => row.id === params.id ? { ...row, [params.field]: params.value } : row )); }; return ( <div style={{ height: 400, width: '100%' }}> <DataGrid rows={rows} columns={columns} onCellEditCommit={handleEditCommit} disableRowSelectionOnClick /> </div> ); }
关键说明
- 完全通过React状态管理按钮状态,避免直接操作DOM,符合React数据流理念
modifiedRowIds集合高效跟踪修改行,适配动态行场景- 编辑提交时同步更新表格数据,保证数据一致性
- 保存完成后自动恢复按钮禁用状态
内容的提问来源于stack exchange,提问作者DavidBuster
相关产品推荐
相关产品推荐

