React页面跳转返回时保留AgGrid状态避免重渲染
React + AgGrid 跨页面保留表格状态方案
问题背景
- 需求:多页面独立使用AgGrid,页面跳转返回时保留表格的筛选、排序、列顺序等用户配置
- 当前问题:使用react-router-dom跳转后返回,AgGrid会重新渲染,之前的状态全部丢失
- 已尝试:将AgGrid提升到父组件,但状态仍会重置,需要
path1和path2各自表格状态独立保留 - 额外要求:不使用
getColumnState/applyColumnState(避免加载延迟),页面刷新时表格恢复默认状态
实现步骤
步骤1:封装通用表格组件
创建MasterTable.js作为基础表格组件:
import React, { useRef } from "react"; import { AgGridReact } from "ag-grid-react"; import "../components/tables/ag-grid-theme-builder.css"; export default function MasterTable({ columns, rowData }) { const gridRef = useRef(); return ( <div className="ag-theme-alpine flex-grow"> <AgGridReact className="ag-theme-custom h-full" ref={gridRef} rowData={rowData} columnDefs={columns} sideBar={{ toolPanels: [ { id: "filters", labelDefault: "筛选", labelKey: "filters", iconKey: "filter", toolPanel: "agFiltersToolPanel", }, { id: "columns", labelDefault: "列配置", labelKey: "columns", iconKey: "columns", toolPanel: "agColumnsToolPanel", toolPanelParams: { suppressRowGroups: true, suppressValues: true, }, }, ], }} /> </div> ); }
步骤2:父组件创建表格实例并配置路由
在App.js中提前创建两个表格实例,确保路由切换时组件实例不被销毁:
import React, { useState } from "react"; import { BrowserRouter, Routes, Route, Link } from "react-router-dom"; import Component from "./Component"; import MasterTable from "./MasterTable"; // 示例假数据 const dummyRowData1 = [ { id: 1, name: "张三", age: 25 }, { id: 2, name: "李四", age: 30 } ]; const dummyColData1 = [ { field: "id", headerName: "ID" }, { field: "name", headerName: "姓名" }, { field: "age", headerName: "年龄" } ]; const dummyRowData2 = [ { product: "手机", price: 3999, stock: 100 }, { product: "电脑", price: 8999, stock: 50 } ]; const dummyColData2 = [ { field: "product", headerName: "商品" }, { field: "price", headerName: "价格" }, { field: "stock", headerName: "库存" } ]; function App() { const [rowData1, setRowData1] = useState(dummyRowData1); const [rowData2, setRowData2] = useState(dummyRowData2); const [colDefs1, setColDefs1] = useState(dummyColData1); const [colDefs2, setColDefs2] = useState(dummyColData2); // 提前创建表格实例,路由切换时实例不会被销毁 const table1 = <MasterTable columns={colDefs1} rowData={rowData1} />; const table2 = <MasterTable columns={colDefs2} rowData={rowData2} />; return ( <BrowserRouter> <nav style={{ padding: "10px" }}> <Link to="/path1/">页面1</Link> | <Link to="/path2/">页面2</Link> </nav> <div style={{ height: "500px", marginTop: "20px" }}> <Routes> <Route path="/path1/" element={<Component table={table1} />} /> <Route path="/path2/" element={<Component table={table2} />} /> </Routes> </div> </BrowserRouter> ); } export default App;
步骤3:页面组件渲染表格
Component.js作为路由页面容器,直接接收并渲染表格实例:
export default function Component({ table }) { return <>{table}</>; }
方案原理
核心是让表格组件实例在路由切换时始终存在:将两个表格实例提前创建在App组件中,作为固定的React元素传递给路由页面。当路由切换时,表格组件只是被React挂载/卸载,而非销毁重建,因此内部状态(筛选、排序、列配置)会被完整保留。同时页面刷新时,App组件重新初始化,表格会回到默认状态,满足需求。
内容的提问来源于stack exchange,提问作者user2603144
相关产品推荐
相关产品推荐

