
本文详解如何在 MUI DataGrid 中正确实现服务端分页,重点解决 onPaginationModelChange 触发后状态未同步、翻页失效等问题,涵盖 paginationModel 双向绑定、offset 计算逻辑及与后端参数映射的关键实践。
本文详解如何在 mui datagrid 中正确实现服务端分页,重点解决 `onpaginationmodelchange` 触发后状态未同步、翻页失效等问题,涵盖 `paginationmodel` 双向绑定、offset 计算逻辑及与后端参数映射的关键实践。
MUI v6+ 的 DataGrid 已弃用旧版 page/pageSize 属性,转而采用受控的 paginationModel(类型为 { page: number; pageSize: number })进行分页管理。若仅监听 onPaginationModelChange 而未将该模型作为 prop 传回组件,分页器将失去响应——这是你点击“下一页”或“上一页”无效的根本原因。
✅ 正确做法:双向绑定 paginationModel
你需要同时满足两个条件:
- 使用 useState 管理当前分页模型;
- 将该模型通过 paginationModel prop 传入 DataGrid;
- 在 onPaginationModelChange 中更新状态,并触发服务端请求(而非仅修改本地 offset)。
const [paginationModel, setPaginationModel] = useState({
page: 0,
pageSize: 5,
});
// 每次分页变更时,计算 offset 并请求新数据
const handlePaginationModelChange = (model: { page: number; pageSize: number }) => {
setPaginationModel(model);
// ✅ 关键:offset = page * pageSize(非 rows.length + 1!)
const newOffset = model.page * model.pageSize;
// 调用你的 API,例如:
fetchRows({ offset: newOffset, limit: model.pageSize });
};
<datagrid rows="{rows}" columns="{columns}" paginationmode="server" rowcount="{totalRowCount}" paginationmodel="{paginationModel}" onpaginationmodelchange="{handlePaginationModelChange}" pagesizeoptions="{[5," loading="{isLoading}" props...></datagrid>
⚠️ 注意事项与常见误区
- offset 不等于 rows.length + 1:服务端分页中,offset 是逻辑偏移量(如第 2 页、每页 5 条 → offset = 1 * 5 = 5),而非前端已有数据长度。错误地使用 rows.length + 1 会导致页码跳变、重复或漏数据。
- 必须设置 rowCount:DataGrid 需要总记录数来渲染正确的页码总数和禁用无效按钮(如最后一页点“下一页”)。该值应来自服务端响应(如 response.total)。
- 启用 paginationMode="server":显式声明可提升可维护性,并确保组件行为符合服务端分页语义(例如隐藏默认页脚中的“显示 X–Y 条”等客户端统计)。
- 避免混合客户端与服务端逻辑:不要在 initialState.pagination.paginationModel 中初始化分页状态;统一由 useState 管理,确保完全受控。
? 补充建议
- 若使用 React Query 或 SWR,可将 paginationModel 作为 query key 的一部分,实现自动缓存与刷新;
- 后端接口建议接收标准参数:?offset=10&limit=5 或 ?page=2&size=5,并在响应中返回 items: [...], total: 127;
- 错误处理时,建议重置 paginationModel 到安全页码(如 page: 0),防止用户停留在无效页。
通过以上配置,DataGrid 将精准响应用户翻页操作,offset 与 pageSize 始终与服务端对齐,彻底解决翻页失效问题。











