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

React AgGrid单条数据时首次加载无法高亮首行问题解决

解决React AgGrid首次插入数据无法高亮首行的问题

问题原因

React的setRowData是异步状态更新,调用后不会立即触发AgGrid的行数据渲染。第一次点击按钮时,你在setRowData后直接调用forEachNode,此时网格还未完成新行的渲染,因此无法获取到行节点;第二次点击时,状态已完成更新,网格已渲染行数据,所以高亮功能正常生效。

解决方案

方案1:使用useEffect监听rowData变化

利用React的useEffect钩子,在rowData更新完成后触发高亮操作,确保网格已经渲染出新行。

修改后的完整代码:

import {AgGridReact} from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';

import {useState, useRef, useEffect, useCallback} from 'react';
import {createOneCarRecord} from './carFactory';

export const AppHighLightFirstRow = () => {
    const gridRef = useRef();
    const [rowData, setRowData] = useState(null);
    const gridAPI = useRef(null); // 改用useRef存储gridAPI,避免全局变量污染
    
    const [columnDefs, setColumnDefs] = useState([
        { field: 'type', sortable: true },
        { field: 'year' },
        { field: 'color' },
        { field: 'price' }
    ]);

    const getRowId = useCallback( params => {
        return params.data.id;
      }, []);

    const onInsertOne = useCallback( ()=> {
        const newRecord = createOneCarRecord();
        setRowData([newRecord]);
      }, []);

    const onGridReady = (params) => {
        params.api.hideOverlay();
        gridAPI.current = params.api;
    };

    // 监听rowData变化,更新后高亮首行
    useEffect(() => {
        if (rowData && rowData.length > 0 && gridAPI.current) {
            const firstRowNode = gridAPI.current.getDisplayedRowAtIndex(0);
            if (firstRowNode) {
                gridAPI.current.flashCells({ 
                    rowNodes: [firstRowNode], 
                    flashDelay: 2000, 
                    fadeDelay: 1000 
                });
            }
        }
    }, [rowData]);

    return (
        <div className="ag-theme-alpine" style={{height: '100%'}}>
            <div><button onClick={onInsertOne}>Insert One</button></div>
            <AgGridReact ref={gridRef}
                enableCellChangeFlash={true}
                getRowId={getRowId}
                rowSelection={'multiple'}
                rowData={rowData} 
                animateRows={true} 
                columnDefs={columnDefs}
                onGridReady={onGridReady}
            />
        </div>
    );
};

方案2:使用AgGrid的onRowDataChanged事件

AgGrid在行数据更新完成后会触发onRowDataChanged事件,我们可以在该事件中执行高亮操作,确保网格已完成行渲染。

修改后的关键代码部分:

export const AppHighLightFirstRow = () => {
    // ...其他状态和钩子保持不变
    const [shouldFlash, setShouldFlash] = useState(false);

    const onInsertOne = useCallback( ()=> {
        const newRecord = createOneCarRecord();
        setRowData([newRecord]);
        setShouldFlash(true); // 设置高亮标记
    }, []);

    const onRowDataChanged = useCallback(() => {
        if (shouldFlash && gridAPI.current) {
            const firstRowNode = gridAPI.current.getDisplayedRowAtIndex(0);
            if (firstRowNode) {
                gridAPI.current.flashCells({ 
                    rowNodes: [firstRowNode], 
                    flashDelay: 2000, 
                    fadeDelay: 1000 
                });
            }
            setShouldFlash(false); // 重置标记
        }
    }, [shouldFlash]);

    return (
        <div className="ag-theme-alpine" style={{height: '100%'}}>
            <div><button onClick={onInsertOne}>Insert One</button></div>
            <AgGridReact ref={gridRef}
                enableCellChangeFlash={true}
                getRowId={getRowId}
                rowSelection={'multiple'}
                rowData={rowData} 
                animateRows={true} 
                columnDefs={columnDefs}
                onGridReady={onGridReady}
                onRowDataChanged={onRowDataChanged} // 添加行数据变化监听
            />
        </div>
    );
};

关键优化点

  1. 替换全局gridAPI为useRef:避免全局变量导致的组件实例间污染问题,确保每个组件持有独立的网格API引用。
  2. 等待行渲染完成:两种方案都确保在网格完成新行渲染后再执行高亮,解决了异步更新导致的行节点获取失败问题。

内容的提问来源于stack exchange,提问作者Raj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 07:35:36