信息发布→ 登录 注册 退出

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

发布时间:2026-01-11

点击量:

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 数据(无函数、Date、undefined、RegExp、Map/Set 等)。若初始数据含复杂类型,请改用 structuredClone()(现代浏览器支持)或 Lodash 的 cloneDeep();
  • 避免在 useEffect 外部或事件处理器中直接修改 rowData 数组或其内部对象——所有变更应通过 setRowData 触发新引用;
  • 如需更高性能或更健壮的还原机制,可结合 onCellValueChanged 监听编辑动作,并维护一份不可变快照(如使用 Immer 或 Redux Toolkit)。

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

标签:# 对象  # 所示  # 更高  # 适用于  # 已有  # 就能  # 是在  # 都是  # 的是  # 已被  # 首次  # 事件  # react  # regexp  # undefined  # map  # 循环  # date  # red  # 一键还原  # 浏览器  # 处理器  # json  # js  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!