React中valueFormatter先于useEffect执行导致网格CurrencyId渲染异常
问题核心原因
你碰到的问题本质是闭包捕获的状态未同步更新:
columnDefs在组件初始化时就已创建,里面的valueFormatter作为闭包,捕获的是初始状态下的currencyCodeList(也就是undefined)。- 即便后续
useEffect请求到数据并更新了currencyCodeList状态,这个旧闭包不会自动刷新,导致valueFormatter始终拿不到最新的货币列表。 - 另外网格可能在两个API请求完成前就开始渲染行数据,此时
currencyCodeList还未加载完成,自然返回undefined。
可行解决办法
方法1:用useMemo动态生成列定义
让columnDefs依赖currencyCodeList,每当货币列表更新时,自动重新生成列定义,确保valueFormatter能捕获到最新状态。
修改后代码示例:
import { useMemo } from 'react'; // 原有状态、useEffect逻辑保持不变 const columnDefs = useMemo(() => [ { field: "currencyId", headerName: "Currency", valueFormatter: (params: any) => { return currencyCodeList?.find((currency) => currency.id === params.value)?.currencyAlphaCode; } }, // 其他列定义... ], [currencyCodeList]); // 依赖currencyCodeList,状态更新时自动重新生成列
方法2:等待所有数据加载完成后再渲染网格
在两个API请求都完成前,不渲染网格或显示加载状态,避免valueFormatter在数据未就绪时执行。
修改后代码示例:
// 原有状态、useEffect逻辑保持不变 // 仅当两类数据都加载完成后才渲染网格 if (!countryDefinitions || !currencyCodeList) { return <div>加载中...</div>; } return ( <AgGridReact rowData={countryDefinitions} columnDefs={columnDefs} // 其他网格配置项... /> );
方法3:通过网格上下文传递货币列表
把currencyCodeList存入网格的context中,在valueFormatter里通过params.context直接获取,绕开闭包限制。
修改后代码示例:
// 原有状态、useEffect逻辑保持不变 return ( <AgGridReact rowData={countryDefinitions} columnDefs={columnDefs} context={{ currencyCodeList }} // 将货币列表传入网格上下文 // 其他网格配置项... /> ); // 列定义中的valueFormatter修改为: const columnDefs = [ { field: "currencyId", headerName: "Currency", valueFormatter: (params: any) => { const currencyList = params.context.currencyCodeList; return currencyList?.find((currency) => currency.id === params.value)?.currencyAlphaCode; } }, // 其他列定义... ];
内容的提问来源于stack exchange,提问作者altunu
相关产品推荐
相关产品推荐

