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

如何可靠判断React AG-Grid组件何时完成数据渲染?

如何可靠判断React AG-Grid组件何时完成数据渲染?

你遇到的这个问题我太熟悉了——用setTimeout凑数确实是无奈之举,不同环境下渲染速度不一样,很容易出现时灵时不灵的情况。其实AG-Grid本身提供了几个更可靠的方式来捕捉数据渲染完成的时机,完全不需要依赖定时器。

方案一:利用modelUpdated事件(最推荐)

AG-Grid的modelUpdated事件是专门用来监听数据模型发生变化并完成UI渲染的时机,不管是首次加载数据,还是后续点击按钮更新数据,只要网格的数据有变动且渲染完成,这个事件就会触发。

步骤很简单:

  1. 给你的AgGridReact组件绑定onModelUpdated回调
  2. 在回调里调用你的autoSizeAll函数

代码示例:

// 先定义事件回调
const handleModelUpdated = useCallback(() => {
  // 先判断数据存在,避免无效调用
  if (rowData && rowData.length > 0) {
    autosizeAll();
  }
}, [rowData, autosizeAll]);

// 在AG-Grid组件中绑定事件
<AgGridReact
  ref={gridRef}
  columnDefs={columnDefs}
  rowData={rowData}
  onModelUpdated={handleModelUpdated}
  // 其他你的配置项...
/>

另外,建议给你的autoSizeAll加个安全判断,避免网格还没初始化完成就调用:

const autoSizeAll = useCallback(() => {
  // 确保gridRef和columnApi都已就绪
  if (!gridRef.current?.columnApi) return;
  
  const allColumnIds = gridRef.current.columnApi.getColumns().map(column => column.colId);
  gridRef.current.columnApi.autoSizeColumns(allColumnIds);
}, [gridRef]);

这个方案是官方推荐的事件驱动方式,完全不依赖定时器,稳定性拉满。

方案二:用waitForDataRendered API 等待渲染完成

如果你更习惯用useEffect监听数据变化,AG-Grid还提供了waitForDataRendered方法,它返回一个Promise,当网格完成当前所有数据的渲染(包括虚拟滚动的行)后才会resolve。

代码示例:

useEffect(() => {
  const autoSizeAfterRender = async () => {
    // 数据为空或网格未初始化时直接返回
    if (!rowData || rowData.length === 0 || !gridRef.current?.api) return;
    
    // 等待网格完成渲染
    await gridRef.current.api.waitForDataRendered();
    // 再调用自动列宽
    autosizeAll();
  };

  autoSizeAfterRender();
}, [rowData, autosizeAll, gridRef]);

这个方式更灵活,适合你需要在特定依赖变化时触发的场景,比如只在rowData或columnDefs变化时执行。

一些额外的注意事项

  • 如果你开启了虚拟滚动,这两个方案都能正常工作,因为它们都会等待可见行渲染完成后再触发。
  • 如果你的数据更新非常频繁,可以给autoSizeAll加个防抖(比如用lodash.debounce),避免频繁调整列宽影响性能。
  • 确保useCallback的依赖项正确,比如gridRef、rowData这些,避免闭包导致拿到旧的实例。

备注:内容来源于stack exchange,提问作者WesternCreamCheese

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 08:08:06