AgGrid 数据恢复失效问题的解决方案

发布时间 - 2026-01-11 00:00:00    点击率:

aggrid 中点击“还原”按钮无法多次恢复原始数据,是因为直接引用了被修改的原始数据对象;需通过深拷贝创建独立副本,确保每次还原都基于初始快照。

在使用 AgGrid 实现可编辑表格时,一个常见需求是提供「还原原始数据」功能。但如示例所示,首次点击还原按钮可成功回退,再次编辑后却失效——根本原因在于:initData.current 存储的是对原始数组的浅引用,而 AgGrid 在编辑单元格(如 price 字段)时,会直接修改 rowData 中的对象属性。由于 JavaScript 对象是引用类型,这些修改会同步反映到 initData.current 所指向的同一内存地址上,导致“原始数据”在第一次编辑后即被污染。

✅ 正确做法:每次还原前生成深拷贝

你不能直接 setRowData(initData.current),而应始终基于初始数据的不可变副本进行还原:

const restore = () => {
  // 使用 JSON 序列化+反序列化实现简易深拷贝(适用于纯JSON数据)
  const freshCopy = JSON.parse(JSON.stringify(initData.current));
  setRowData(freshCopy);
};
⚠️ 注意:JSON.parse(JSON.stringify(obj)) 是一种轻量级深拷贝方式,适用于不含函数、undefined、Date、RegExp、Map/Set 等特殊类型的纯数据对象。若你的原始数据结构更复杂,建议使用 lodash.cloneDeep() 或结构化克隆(structuredClone(),现代浏览器支持):// 更健壮的替代方案(推荐生产环境) const freshCopy = structuredClone(initData.current); // 或:import { cloneDeep } from 'lodash'; const freshCopy = cloneDeep(initData.current);

? 补充优化建议

  • 初始化时机要可靠:useEffect 中调用异步 Promise 时,应添加清理机制防止状态更新在组件卸载后执行(避免警告或异常),例如:

    useEffect(() => {
      let isMounted = true;
      myPromise.then(data => {
        if (isMounted) {
          setRowData(data);
          initData.current = structuredClone(data); // 初始化即深拷贝,更安全
        }
      });
      return () => { isMounted = false; };
    }, []);
  • 避免重复渲染陷阱:确保 initData.current 仅在初始加载时赋值一次,且不参与 useState 或 useEffect 依赖数组,否则可能触发意外重置。

  • UI 反馈增强:可在 restore 按钮中添加禁用态或加载提示,提升用户体验,例如结合 useState 控制按钮状态。

通过强制每次还原都使用全新数据实例,即可彻底解决 AgGrid 多次编辑后无法还原的问题——核心原则始终是:原始数据必须 Immutable(不可变)


# javascript  # java  # js  # json  # 浏览器  # 数据恢复  # red 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: ,南京靠谱的征婚网站?  JavaScript如何实现路由_前端路由原理是什么  移动端脚本框架Hammer.js  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  高防服务器租用首荐平台,企业级优惠套餐快速部署  如何快速搭建高效服务器建站系统?  Python面向对象测试方法_mock解析【教程】  ,怎么在广州志愿者网站注册?  Laravel如何使用Eloquent进行子查询  如何在万网开始建站?分步指南解析  bootstrap日历插件datetimepicker使用方法  Android自定义控件实现温度旋转按钮效果  如何在云服务器上快速搭建个人网站?  Laravel怎么使用artisan命令缓存配置和视图  Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】  Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)  如何在云指建站中生成FTP站点?  html文件怎么打开证书错误_https协议的html打开提示不安全【指南】  Laravel怎么在Blade中安全地输出原始HTML内容  用v-html解决Vue.js渲染中html标签不被解析的问题  Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用  高端建站三要素:定制模板、企业官网与响应式设计优化  北京网站制作公司哪家好一点,北京租房网站有哪些?  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  Python制作简易注册登录系统  Laravel Seeder填充数据教程_Laravel模型工厂Factory使用  如何快速使用云服务器搭建个人网站?  SQL查询语句优化的实用方法总结  免费视频制作网站,更新又快又好的免费电影网站?  Claude怎样写约束型提示词_Claude约束提示词写法【教程】  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法  无锡营销型网站制作公司,无锡网选车牌流程?  edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】  详解jQuery停止动画——stop()方法的使用  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  详解jQuery中基本的动画方法  laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析  Android利用动画实现背景逐渐变暗  Laravel如何与Pusher实现实时通信?(WebSocket示例)  Linux安全能力提升路径_长期防护思维说明【指导】  制作公司内部网站有哪些,内网如何建网站?  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】  详解Android中Activity的四大启动模式实验简述  Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】  详解jQuery中的事件  今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】  Internet Explorer官网直接进入 IE浏览器在线体验版网址