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

React MUI X Data Grid编辑异常:无法退出编辑模式及TypeError报错求助

问题原因与修复方案

1. 无法退出编辑模式

processRowUpdate 要求必须返回更新后的行数据,DataGrid 才会确认编辑完成并退出编辑状态。当前处理函数未返回值,导致组件一直停留在编辑模式。

2. TypeError: Cannot read properties of undefined (reading 'id')

  • 对processRowUpdate参数结构理解错误:更新后的行数据在参数的row属性中,而非直接取params.id;
  • 直接修改 state 中原数组punteos,违反 React 不可变数据原则,同时固定循环12次,当数组长度不足时会访问undefined的id属性;
  • 未显式指定getRowId属性,可能导致 DataGrid 无法正确识别行的唯一标识。

修改后的完整代码

import React, { Component } from "react"
import ScoreDataService from "../../services/score.service";
import { Link } from "react-router-dom";
import { DataGrid } from '@mui/x-data-grid';

export default class StudentList extends Component {
  constructor(props) {
    super(props);
    this.ObtenerPunteos = this.ObtenerPunteos.bind(this);
    this.GuardarPunteos = this.GuardarPunteos.bind(this);
    this.Reset = this.Reset.bind(this);

    this.state = {
      punteos: [],
      punteos_viejos: [],
      isUpdated: false,
    };
  }

  componentDidMount() {
    this.ObtenerPunteos();
  }

  Reset(){
    this.setState(prevState => ({
      punteos: prevState.punteos_viejos,
      isUpdated: false
    }));
  }

  ObtenerPunteos() {
    ScoreDataService.getAll(7)
      .then(response => {
        this.setState({
          punteos: response.data,
          punteos_viejos: response.data
        });
      })
      .catch(e => {
        console.log(e);
      });
  }

  GuardarPunteos(){
    const { punteos } = this.state;
    // 替换为你的后端批量更新接口
    ScoreDataService.updateAll(punteos)
      .then(() => {
        this.setState({
          punteos_viejos: punteos,
          isUpdated: false
        });
      })
      .catch(e => {
        console.log(e);
      });
  }

  handleEditCellChange = ({ row }) => {
    // 生成新数组,遵循不可变数据原则
    const updatedPunteos = this.state.punteos.map(item => 
      item.id === row.id ? { ...item, ...row } : item
    );
    
    this.setState({
      punteos: updatedPunteos,
      isUpdated: true
    });
    
    // 返回更新后的行,让DataGrid确认编辑完成
    return row;
  };

  handleProcessRowUpdateError = (error) => {
    console.log('编辑更新错误:', error);
  };

  render() {
    const { punteos, isUpdated } = this.state;
    const columns = [
      { field: 'id', headerName: 'id', width: 70, editable: false },
      { field: 'curso', headerName: 'Curso', width: 200, editable: false },
      { field: 'nota1', headerName: 'Bimestre 1', width: 130, editable: true, type: 'number'},
      { field: 'nota2', headerName: 'Bimestre 2', width: 130, editable: true, type: 'number'},
      { field: 'nota3', headerName: 'Bimestre 3', width: 130, editable: true, type: 'number' },
      { field: 'nota4', headerName: 'Bimestre 4', width: 130, editable: true, type: 'number' },
    ];

    return(
      <div style={{ height: 800, width: '100%' }}>
        {punteos.length > 0 ? (
          <DataGrid
            rows={punteos}
            columns={columns}
            pageSize={5}
            rowsPerPageOptions={[5]}
            processRowUpdate={this.handleEditCellChange}
            onProcessRowUpdateError={this.handleProcessRowUpdateError}
            getRowId={(row) => row.id}
          />
        ) : (
          <div>加载中...</div>
        )}
        <button onClick={this.GuardarPunteos} disabled={!isUpdated}>保存</button>
        <button onClick={this.Reset} disabled={!isUpdated}>重置</button>
      </div>
    );  
  }
}

关键修改点说明

  • 退出编辑模式修复:在handleEditCellChange末尾返回更新后的row,让DataGrid确认编辑完成;
  • TypeError修复:
    • 正确解构参数,从row中获取更新后的数据;
    • 使用map生成新数组,避免直接修改原state数组,同时遍历所有数组元素而非固定次数;
    • 显式配置getRowId,确保DataGrid正确识别行唯一标识;
  • 功能优化:
    • 重置功能直接恢复为原始备份数据;
    • 移除componentDidMount中不必要的函数调用;
    • 完善保存逻辑,添加后端接口调用,保存成功后更新原始数据备份。

内容的提问来源于stack exchange,提问作者Javier Morales

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:27:57