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
相关产品推荐
相关产品推荐

