You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 17:21:05