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

React中点击按钮删除Kendo Grid项时出现Cannot read properties of undefined (reading 'ProductID')报错的解决方法

解决Kendo Grid点击删除按钮报错"Cannot read properties of undefined (reading 'ProductID')"的问题

我来帮你搞定这个问题!你遇到的这个错误主要是三个小细节没处理好,咱们逐个修正就能实现正常删除功能了:

  • 删除函数调用时未传递当前行数据:你在MyCommandCell里的按钮点击事件调用deleteItem()时没有传入当前要删除的条目,导致deleteItem函数里的item是undefined,自然会报错找不到ProductID。
  • 错误操作原始数据而非组件状态:组件渲染用的是useState维护的data状态,但你在deleteItem里直接修改了原始的sampleProducts数组,这完全不符合React的状态更新逻辑,应该通过setData来更新状态。
  • 自定义单元格未接收当前行数据:Kendo Grid的自定义cell组件会自动传入包含当前行dataItem的props,你需要从props里取出这个数据传递给删除函数。

完整修正代码

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Grid, GridColumn as Column } from '@progress/kendo-react-grid';
import { sampleProducts } from './sample-products';

const allInEdit = sampleProducts.map((item) => Object.assign(
  { inEdit: true, },
  item
));

const App = () => {
  const [data, setData] = React.useState(allInEdit);

  // 修正后的删除函数:基于当前状态生成新数组并更新状态
  const deleteItem = (item) => {
    // 用filter生成排除目标条目的新数组,符合React不可变状态原则
    const newData = data.filter(record => record.ProductID !== item.ProductID);
    setData(newData);
  };

  // 自定义单元格组件:接收props并取出当前行的dataItem
  const MyCommandCell = (props) => {
    return (
      <button 
        className="k-button k-grid-remove-command" 
        onClick={() => deleteItem(props.dataItem)}
      >
        Remove
      </button>
    );
  };

  const itemChange = (e) => {
    let newData = data.map((item) => {
      if (item.ProductID === e.dataItem.ProductID) {
        // 用对象展开创建新对象,避免直接修改原item(遵循不可变原则)
        return { ...item, [e.field || '']: e.value };
      }
      return item;
    });
    setData(newData);
  };

  return (
    <Grid data={data} editField="inEdit" onItemChange={itemChange}>
      <Column field="ProductID" title="Id" width="50px" editable={false} />
      <Column field="ProductName" />
      <Column field="FirstOrderedOn" editor="date" format="{0:d}" />
      <Column field="UnitsInStock" width="150px" />
      <Column field="Discontinued" width="50px" editor="boolean" />
      <Column cell={MyCommandCell} width="240px" />
    </Grid>
  );
};

ReactDOM.render(<App />, document.querySelector('my-app'));

额外优化说明

  • 把deleteItem和MyCommandCell移到App组件内部,这样它们可以直接访问组件的状态和状态更新方法,避免作用域问题。
  • 使用filter替代splice来删除条目:splice会直接修改原数组,而filter返回全新数组,更符合React的不可变状态更新规范,能避免很多意外的渲染问题。
  • 在itemChange里用对象展开创建新对象,而不是直接修改原item,同样是遵循不可变状态的原则,让状态更新更可预测。

内容的提问来源于stack exchange,提问作者Phat Baba

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 19:32:33