React MUI DataGrid服务端分页失效问题求助
修复DataGrid服务端分页失效问题
问题场景
我基于DataGrid实现服务端分页,要求后端每次返回指定条数(比如5条)的数据,通过offset参数告知后端数据起始索引。已添加状态const [offset, setOffset] = useState(0)管理偏移量,但点击分页按钮(上/下一页)完全失效,当前实现的核心代码如下:
const [offset, setOffset] = useState(0); const handlePageChange = (newOffset, newLimit) => { setOffset(newOffset); }; <DataGrid rows={rows} className="grid-container" columns={columns} hideFooter={rows?.length < 5} initialState={{ pagination: { paginationModel: { pageSize: 5, page: 0 }, }, }} pageSizeOptions={[5, 10, 25]} autoHeight={false} autoWidth={false} {...rest} localeText={{ noRowsLabel: ( <Typography variant="h5" component="h2" fontWeight="normal"> No Data </Typography> ), }} onPaginationModelChange={(params) => { const newOffset = rows?.length + 1; handlePageChange(newOffset); }} slots={{ toolbar: toolbar, }} loading={isLoading} />
错误原因
- Offset计算逻辑错误:用
rows?.length +1计算偏移量完全不符合服务端分页规则——比如当前页返回5条数据,下一页的offset应该是5,而非5+1=6;点击上一页时,该逻辑也无法正确回退offset。 - 未同步分页状态:没有将本地的
offset状态和DataGrid的paginationModel绑定,导致组件无法识别当前分页位置,分页按钮状态异常。 - 未启用服务端分页模式:默认情况下DataGrid使用本地分页,必须显式声明服务端模式才能让组件适配后端分页逻辑。
修复方案
核心调整点
- 改用
page * pageSize计算offset:这是服务端分页的标准逻辑(page从0开始计数),避免依赖本地数据长度导致的错误。 - 绑定
paginationModel与本地状态:让DataGrid的分页显示与实际请求的offset保持一致。 - 开启
paginationMode="server":告知组件禁用本地分页,完全依赖后端返回的数据。
完整修复代码
import { useState, useEffect } from 'react'; import { DataGrid, Typography } from '@mui/x-data-grid'; // 示例:后端数据请求函数,根据offset和limit获取数据 const fetchServerData = async (offset, limit) => { const res = await fetch(`/your-api-endpoint?offset=${offset}&limit=${limit}`); return res.json(); }; const YourDataGridComponent = ({ columns, toolbar, ...rest }) => { const [offset, setOffset] = useState(0); const [rows, setRows] = useState([]); const [isLoading, setIsLoading] = useState(false); const [pageSize, setPageSize] = useState(5); // 分页变更或pageSize切换时,重新请求后端数据 const loadData = async () => { setIsLoading(true); const data = await fetchServerData(offset, pageSize); setRows(data); setIsLoading(false); }; // 组件初始化、offset或pageSize变更时触发数据请求 useEffect(() => { loadData(); }, [offset, pageSize]); return ( <DataGrid rows={rows} className="grid-container" columns={columns} // 当当前页数据不足一页时隐藏分页栏 hideFooter={rows?.length < pageSize} // 绑定分页模型,同步本地状态与组件显示 paginationModel={{ page: offset / pageSize, pageSize }} pageSizeOptions={[5, 10, 25]} autoHeight={false} autoWidth={false} {...rest} localeText={{ noRowsLabel: ( <Typography variant="h5" component="h2" fontWeight="normal"> No Data </Typography> ), }} // 处理分页变更,计算正确offset并更新状态 onPaginationModelChange={(newModel) => { const { page, pageSize: newPageSize } = newModel; const newOffset = page * newPageSize; setOffset(newOffset); setPageSize(newPageSize); }} slots={{ toolbar: toolbar, }} loading={isLoading} // 开启服务端分页模式 paginationMode="server" /> ); }; export default YourDataGridComponent;
关键注意事项
paginationMode="server"是必须的,它会让DataGrid不再对本地数据进行分页处理,完全依赖后端返回的结果。- 当用户切换pageSize时,
onPaginationModelChange会同步更新pageSize状态,同时重新计算offset,确保请求的起始位置正确。 - 后端接口需要正确接收
offset和limit参数,返回对应区间的数据,若需要显示总页数,可通过rowCount属性传递总数据条数给DataGrid。
内容的提问来源于stack exchange,提问作者ganesh kaspate
相关产品推荐
相关产品推荐

