Ag-Grid React结合Redux:服务端行模型数据更新同步问题
在Ag-Grid React服务端行模型中处理Redux状态更新问题
问题核心
服务端行模型的datasource初始化后,其getRows函数会形成闭包捕获当时的Redux状态值,后续Redux状态更新时,闭包不会自动同步最新值,且Ag-Grid不会主动触发重新请求,导致表格无法感知状态变化。
有效解决方案
1. 监听Redux状态变化,手动触发表格刷新
使用useEffect监听目标Redux状态(比如toolImages),当状态更新时,调用Ag-Grid的refreshServerSideStore API强制重新拉取数据:
import { useSelector } from 'react-redux'; import { useEffect, useRef } from 'react'; import { AgGridReact } from 'ag-grid-react'; const YourGridComponent = () => { const toolImages = useSelector(state => state.yourReducer.toolImages); const gridApiRef = useRef(null); const onGridReady = (params) => { gridApiRef.current = params.api; // 初始化数据源 params.api.setGridOption('datasource', { getRows: (params) => { // 基于最新状态发起请求 fetch(`/your-api-endpoint?toolImages=${JSON.stringify(toolImages)}`) .then(res => res.json()) .then(data => { params.success({ rowData: data.rows, rowCount: data.total }); }) .catch(err => params.fail()); } }); }; // 状态变化时触发表格刷新 useEffect(() => { if (gridApiRef.current) { // purge: true 清空现有缓存,重新请求全量数据;设为false仅刷新当前视图数据 gridApiRef.current.refreshServerSideStore({ purge: true }); } }, [toolImages]); return ( <AgGridReact rowModelType="serverSide" onGridReady={onGridReady} // 其他表格配置项... /> ); };
2. 使用Ref保存最新状态,规避闭包陷阱
如果getRows是异步执行的,闭包可能捕获旧状态,这时用useRef实时同步最新的Redux状态:
const YourGridComponent = () => { const toolImages = useSelector(state => state.yourReducer.toolImages); const toolImagesRef = useRef(toolImages); const gridApiRef = useRef(null); // 同步最新状态到Ref useEffect(() => { toolImagesRef.current = toolImages; }, [toolImages]); const onGridReady = (params) => { gridApiRef.current = params.api; params.api.setGridOption('datasource', { getRows: (params) => { // 从Ref中获取最新状态 const latestToolImages = toolImagesRef.current; fetch(`/your-api-endpoint?toolImages=${JSON.stringify(latestToolImages)}`) .then(res => res.json()) .then(data => { params.success({ rowData: data.rows, rowCount: data.total }); }) .catch(err => params.fail()); } }); }; return ( <AgGridReact rowModelType="serverSide" onGridReady={onGridReady} // 其他表格配置项... /> ); };
3. 动态更新Datasource
当Redux状态变化时,生成新的datasource对象并传递给表格,确保getRows能获取最新状态:
const YourGridComponent = () => { const toolImages = useSelector(state => state.yourReducer.toolImages); const gridApiRef = useRef(null); // 基于toolImages生成新的datasource const datasource = useCallback({ getRows: (params) => { fetch(`/your-api-endpoint?toolImages=${JSON.stringify(toolImages)}`) .then(res => res.json()) .then(data => { params.success({ rowData: data.rows, rowCount: data.total }); }) .catch(err => params.fail()); } }, [toolImages]); const onGridReady = (params) => { gridApiRef.current = params.api; params.api.setGridOption('datasource', datasource); }; // 状态变化时更新datasource并触发刷新 useEffect(() => { if (gridApiRef.current) { gridApiRef.current.setGridOption('datasource', datasource); gridApiRef.current.refreshServerSideStore({ purge: true }); } }, [datasource]); return ( <AgGridReact rowModelType="serverSide" onGridReady={onGridReady} // 其他表格配置项... /> ); };
关键注意点
- 服务端行模型不会自动监听外部状态变化,必须手动触发刷新或更新datasource
- 避免在
getRows中依赖闭包中的旧状态,优先用Ref或直接从Store获取最新值 - 根据业务需求选择
refreshServerSideStore的purge参数,控制是否清空缓存
内容的提问来源于stack exchange,提问作者Mina Fawzy
相关产品推荐
相关产品推荐

