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

DataGrid行内按钮Enable/Disable状态控制问题求助

解决方案:通过React状态管理控制按钮禁用状态

直接操作DOM(比如document.getElementById)在React里不是推荐做法,因为组件渲染由状态驱动,DOM操作会和React虚拟DOM更新冲突。正确方式是用状态跟踪哪些行发生了修改,再根据状态动态控制按钮的禁用状态。

以下是具体实现步骤:

  1. 添加状态跟踪修改的行
    用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());
    
  2. 更新编辑提交逻辑
    在编辑提交时判断值是否真的变化,同步更新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
        ));
    };
    
  3. 动态控制按钮禁用状态
    在renderCell里,根据当前行ID是否在modifiedRowIds中设置按钮状态:

    { 
        field: 'button', 
        headerName: '操作', 
        width: 120,
        renderCell: (cellValues) => (
            <button 
                onClick={() => handleButton(cellValues.id)} 
                disabled={!modifiedRowIds.has(cellValues.id)}
            >
                保存
            </button>
        ) 
    }
    
  4. 完善按钮点击逻辑
    点击保存后移除对应行的修改标记,按钮恢复禁用:

    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 05:06:25