在React项目中使用AG Grid开发数据表格时,实现无限滚动功能可以有效优化大数据量场景下的加载性能,而服务端数据源的正确配置是支撑无限滚动稳定运行的核心。通过服务端数据源,AG Grid可以在用户滚动到表格底部时自动请求下一页数据,无需手动翻页操作。

AG Grid无限滚动基础配置
首先需要在React组件中引入AG Grid相关依赖,并开启无限滚动的基础开关。核心配置项是rowModelType设置为serverSide,同时开启suppressServerSideInfiniteScroll为false。
import React, { useRef, useState } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
const AgGridInfiniteScroll = () => {
const gridRef = useRef(null);
const [columnDefs] = useState([
{ field: 'id', headerName: 'ID' },
{ field: 'name', headerName: '名称' },
{ field: 'age', headerName: '年龄' },
{ field: 'email', headerName: '邮箱' }
]);
const defaultColDef = {
sortable: true,
filter: true,
resizable: true
};
return (
<div className="ag-theme-alpine" style={{ height: 500, width: '100%' }}>
<AgGridReact
ref={gridRef}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
rowModelType="serverSide"
suppressServerSideInfiniteScroll={false}
cacheBlockSize={20}
maxBlocksInCache={10}
/>
</div>
);
};
export default AgGridInfiniteScroll;
服务端数据源配置核心逻辑
服务端数据源需要实现一个getRows方法,该方法会在AG Grid需要加载数据时自动调用,接收请求参数并返回对应的数据。请求参数中包含起始行、结束行、排序、筛选等信息,我们可以根据这些信息向服务端发起请求。
const dataSource = {
getRows: async (params) => {
// 从请求参数中获取分页信息
const { startRow, endRow, sortModel, filterModel } = params;
// 计算当前请求的页码和每页条数
const pageSize = endRow - startRow;
const pageNum = Math.floor(startRow / pageSize) + 1;
try {
// 向服务端发起请求,这里替换为实际的接口地址
const response = await fetch(`https://ipipp.com/api/data?pageNum=${pageNum}&pageSize=${pageSize}&startRow=${startRow}&endRow=${endRow}`);
const result = await response.json();
// 成功返回数据,调用params.success回调
if (result.code === 200) {
params.success({
rowData: result.data.list,
rowCount: result.data.total // 总条数,用于AG Grid判断是否可以继续滚动加载
});
} else {
// 请求失败,调用params.fail回调
params.fail();
}
} catch (error) {
params.fail();
}
}
};
// 在网格就绪后设置数据源
const onGridReady = (params) => {
params.api.setServerSideDatasource(dataSource);
};
将上述onGridReady方法绑定到AG Grid的onGridReady事件上即可完成数据源的设置。
服务端接口适配要求
为了配合AG Grid的无限滚动请求,服务端接口需要支持以下参数:
- startRow:当前请求数据的起始行索引,从0开始
- endRow:当前请求数据的结束行索引,不包含该索引对应的数据
- pageNum:可选,当前请求的页码,方便服务端分页处理
- pageSize:可选,每页数据条数,和cacheBlockSize配置保持一致
服务端返回的数据结构需要包含数据列表和总条数,示例如下:
{
"code": 200,
"data": {
"list": [
{ "id": 1, "name": "张三", "age": 25, "email": "zhangsan@ipipp.com" },
{ "id": 2, "name": "李四", "age": 28, "email": "lisi@ipipp.com" }
],
"total": 1000
},
"message": "请求成功"
}
常见问题与优化
数据重复或缺失问题
如果出现数据重复或缺失,通常是rowCount返回不正确导致的。如果服务端无法返回准确的总条数,可以将rowCount设置为undefined,AG Grid会自动根据返回的数据量判断是否可以继续加载。
加载状态优化
可以在getRows方法执行前后添加加载状态提示,提升用户体验。AG Grid提供了loading属性,也可以通过自定义遮罩层实现。
缓存配置优化
cacheBlockSize表示每次请求的数据条数,maxBlocksInCache表示最多缓存多少个数据块,合理调整这两个参数可以平衡内存占用和加载性能。如果数据更新不频繁,可以适当增大maxBlocksInCache的值。
完整示例代码
import React, { useRef, useState } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
const AgGridInfiniteScroll = () => {
const gridRef = useRef(null);
const [columnDefs] = useState([
{ field: 'id', headerName: 'ID' },
{ field: 'name', headerName: '名称' },
{ field: 'age', headerName: '年龄' },
{ field: 'email', headerName: '邮箱' }
]);
const defaultColDef = {
sortable: true,
filter: true,
resizable: true
};
const dataSource = {
getRows: async (params) => {
const { startRow, endRow } = params;
const pageSize = endRow - startRow;
const pageNum = Math.floor(startRow / pageSize) + 1;
try {
const response = await fetch(`https://ipipp.com/api/data?pageNum=${pageNum}&pageSize=${pageSize}`);
const result = await response.json();
if (result.code === 200) {
params.success({
rowData: result.data.list,
rowCount: result.data.total
});
} else {
params.fail();
}
} catch (error) {
params.fail();
}
}
};
const onGridReady = (params) => {
params.api.setServerSideDatasource(dataSource);
};
return (
<div className="ag-theme-alpine" style={{ height: 500, width: '100%' }}>
<AgGridReact
ref={gridRef}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
rowModelType="serverSide"
suppressServerSideInfiniteScroll={false}
cacheBlockSize={20}
maxBlocksInCache={10}
onGridReady={onGridReady}
/>
</div>
);
};
export default AgGridInfiniteScroll;