如何在 Ag-Grid 中正确恢复原始数据(避免浅拷贝导致的还原失效)

11次阅读

如何在 Ag-Grid 中正确恢复原始数据(避免浅拷贝导致的还原失效)

ag-grid 编辑后多次点击“还原”按钮失效,根本原因是原始数据被直接引用并修改,导致 `initdata.current` 在首次还原后已非初始状态;需每次还原时创建深拷贝,而非复用已被污染的引用。

在使用 Ag-Grid 的 react 版本时,若需支持「编辑后一键还原至初始数据」功能,一个常见但易被忽视的陷阱是:对初始数据仅做一次浅层保存,后续还原却未隔离引用关系。如示例代码所示,initData.current = jsON.parse(json.stringify(data)) 确实在初始化时生成了深拷贝,但 restore() 函数中直接赋值 setRowData(initData.current) 会导致第二次还原时操作的是已被 Grid 内部或 React 状态更新间接修改过的同一对象引用(尤其当单元格编辑触发了对象属性变更且未强制克隆时)。

本质上,rowData 是受控的 React 状态,而 Ag-Grid 在编辑过程中可能直接修改传入的行对象(例如启用 immutableData={false} 默认行为),这会使 initData.current 所指向的对象在首次编辑后即被污染。因此,每次还原都必须生成全新的、独立的数据副本

✅ 正确做法是在 restore 函数中即时执行深拷贝:

const restore = () => {   // 每次点击都创建全新深拷贝,确保与任何已有引用完全隔离   const freshCopy = JSON.parse(JSON.stringify(initData.current));   setRowData(freshCopy); };

⚠️ 注意事项:

  • JSON.parse(JSON.stringify(obj)) 是快速深拷贝方案,适用于纯 JSON 数据(无函数、dateundefinedregexpmap/Set 等)。若初始数据含复杂类型,请改用 structuredClone()(现代浏览器支持)或 Lodash 的 cloneDeep();
  • 避免在 useEffect 外部或事件处理器中直接修改 rowData 数组或其内部对象——所有变更应通过 setRowData 触发新引用;
  • 如需更高性能或更健壮的还原机制,可结合 onCellValueChanged 监听编辑动作,并维护一份不可变快照(如使用 Immer 或 redux Toolkit)。

总结:Ag-Grid 的还原逻辑不是“重置引用”,而是“重置数据内容”。只要保证每次 setRowData 接收的都是与之前完全无关的新对象树,就能稳定实现多轮编辑→还原循环

text=ZqhQzanResources