MUI DataGrid服务端分页问题:分页箭头处于禁用状态
MUI DataGrid服务端分页下一页箭头禁用问题排查
问题概述
在React ^17.0.2 + @mui/x-data-grid ^6.6.0环境下开发服务端分页的DataGrid页面,首次加载数据正常,但分页组件的下一页箭头始终处于禁用状态。
环境依赖
react: ^17.0.2@mui/x-data-grid: ^6.6.0
原代码
import React, { useState, useEffect } from "react"; import { DataGrid } from "@mui/x-data-grid"; const TestPager = (props) => { const [customers, setCustomers] = useState([]); const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(2); useEffect(() => { const fetchCustomers = async () => { const response = await fetch(`/api/paged-list?page=${page}&pageSize=${pageSize}`); const data = await response.json(); setCustomers(data.Data); setPage(data.Page); setPageSize(data.PageSize); }; fetchCustomers(); }, [page, pageSize]); const paginationFunction = async (params) => { const response = await fetch(`/api/paged-list?page=${params.page}&pageSize=${params.pageSize}`); const data = await response.json(); setCustomers(data.Data); return { rows: data.Data, pageCount: 3 }; }; const columns = [ { field: "Id", headerName: "ID" }, { field: "Name", headerName: "Name" } ]; return ( <> <div id="loadSpinners" style={{ height: "8px" }}></div> <DataGrid rows={customers} columns={columns} paginationMode="server" rowCount={6} getRowId={(row) => row.Id} paginationFunction={paginationFunction} onPaginationModelChange={(c) => { setPage(c.page); setPageSize(c.pageSize); }} /> </> ); }; export default TestPager;
已尝试方案
- 遵循MUI官方文档服务端分页示例实现,问题未解决;
- 参考AI生成的示例代码,问题依旧。
问题原因及解决方案
核心问题分析
- 页码索引不匹配:DataGrid的分页页码采用0起始索引,但后端API使用1起始索引,两者未做转换,导致分页状态判断错误;
- 逻辑冗余导致状态冲突:同时使用
paginationFunction(官方服务端分页处理函数)和onPaginationModelChange+useEffect的自定义请求逻辑,两种方式同时修改状态,导致DataGrid内部分页状态与本地维护的page/pageSize不一致; - 硬编码
pageCount:返回固定的pageCount:3,未与实际总数据量和页大小动态关联,可能导致分页控件状态计算错误。
修复后的代码
import React, { useState } from "react"; import { DataGrid } from "@mui/x-data-grid"; const TestPager = (props) => { const [customers, setCustomers] = useState([]); const [totalCount, setTotalCount] = useState(6); // 初始值可由后端返回,或设为0后续更新 const paginationFunction = async (params) => { // 将DataGrid的0-based页码转换为后端需要的1-based const apiPage = params.page + 1; const response = await fetch(`/api/paged-list?page=${apiPage}&pageSize=${params.pageSize}`); const data = await response.json(); setCustomers(data.Data); setTotalCount(data.TotalCount); // 假设后端返回总数据条数 // 动态计算总页数,或直接使用后端返回的TotalPages return { rows: data.Data, pageCount: Math.ceil(data.TotalCount / params.pageSize) }; }; const columns = [ { field: "Id", headerName: "ID" }, { field: "Name", headerName: "Name" } ]; return ( <> <div id="loadSpinners" style={{ height: "8px" }}></div> <DataGrid rows={customers} columns={columns} paginationMode="server" rowCount={totalCount} // 绑定实际总数据条数 getRowId={(row) => row.Id} paginationFunction={paginationFunction} // 移除冗余的onPaginationModelChange和本地page/pageSize状态 /> </> ); }; export default TestPager;
关键修复点说明
- 统一页码转换:在
paginationFunction中把DataGrid传入的params.page(0起始)加1,转换为后端需要的1起始页码; - 移除冗余逻辑:删除本地维护的
page/pageSize状态、useEffect请求逻辑和onPaginationModelChange回调,完全依赖paginationFunction处理服务端分页请求; - 动态计算分页参数:通过后端返回的总数据条数
TotalCount动态计算pageCount,或直接使用后端返回的总页数,确保分页控件能正确判断按钮禁用状态; - 绑定真实总条数:
rowCount设置为实际总数据条数,而非固定值,让DataGrid能准确计算分页边界。
内容的提问来源于stack exchange,提问作者h4ck3r8ug5
相关产品推荐
相关产品推荐

