MUI DataGrid中setPage无法切换页面的问题求助
MUI DataGrid 分页不生效问题修复
问题描述
分页组件的setPage功能正常,浏览器控制台能看到页码数值变化,但MUI DataGrid本身不会切换页面。静态在useState中设置页码时,DataGrid可正确显示对应页面。
原始代码
DataGrid 组件
import { FC } from "react"; import { Paper, Stack, Typography } from "@mui/material"; import { DataGrid, GridToolbar, GridColDef } from "@mui/x-data-grid"; const CustomDataGrid: FC<{ tableTitle: string; rowsData: any; columnsData: GridColDef[]; currentPage: number; pageSize: number; getRowId?: (params: any) => any; error?: any; NoDataMsg: string; NoResultMsg: string; }> = ({ tableTitle, rowsData, columnsData, currentPage, pageSize, getRowId, error, NoDataMsg, NoResultMsg }) => { return ( <Paper elevation={4} style={{ marginBottom: "10px", borderRadius: "10px" }}> <Typography textAlign="center" variant="h5" style={{ paddingTop: "20px", paddingBottom: "40px", fontWeight: "bold" }} > {tableTitle} </Typography> <DataGrid columns={columnsData} rows={rowsData} rowHeight={64} initialState={{ pagination: { paginationModel: { pageSize: pageSize, page: currentPage - 1 } } }} ignoreDiacritics hideFooterPagination disableRowSelectionOnClick disableColumnFilter disableColumnMenu disableColumnSelector disableDensitySelector hideFooterSelectedRowCount getRowId={getRowId} autoHeight={true} slotProps={{ toolbar: { showQuickFilter: true } }} slots={{ toolbar: GridToolbar, noRowsOverlay: () => ( <Stack height="100%" alignItems="center" justifyContent="center"> <Typography variant="h4" sx={{ fontSize: "24px", color: error ? "error.main" : "primary.main" }} > { NoDataMsg } </Typography> </Stack> ), noResultsOverlay: () => ( <Stack height="100%" alignItems="center" justifyContent="center"> <Typography variant="h4" sx={{ fontSize: "24px", color: "primary.main" }}> { NoResultMsg } </Typography> </Stack> ) }} /> </Paper> ); }; export default CustomDataGrid;
分页组件
import { FC } from "react"; import { Pagination } from "@mui/material"; const CustomPagination: FC<{ page: number; setPage: (params: any) => any; totalRows: number; pageSize: number; }> = ({ page, setPage, pageSize, totalRows }) => { return ( <Pagination count={Math.ceil(totalRows / pageSize)} variant="outlined" shape="rounded" page={page} hideNextButton hidePrevButton size="small" sx={{ width: "100%" }} onChange={(e) => { const target = e.target as HTMLElement; setPage(Number(target.innerText)); }} /> ); }; export default CustomPagination;
App.tsx
import { useState } from 'react' import { GridColDef } from "@mui/x-data-grid"; import { clinicsData } from "../data"; import CustomDataGrid from './comps/datagridComp'; import CustomPagination from './comps/paginationComp'; function App() { const pageSize = 7; const [page, setPage] = useState(1); const columns: GridColDef[] = [ { field: "name", headerName: "Name", flex: 1, headerAlign: "center", sortable: false } ]; console.log(page) return ( <> <CustomDataGrid tableTitle='Clinics Table' getRowId={(row) => row.id} columnsData={columns} rowsData={clinicsData} currentPage={page} pageSize={pageSize} // error={error} NoDataMsg={"No Data Available"} NoResultMsg={"No Data Matching"} /> {clinicsData.length / pageSize > 1 && ( <CustomPagination page={page} setPage={setPage} pageSize={pageSize} totalRows={clinicsData.length} /> )} </> ) } export default App
问题原因
DataGrid的initialState仅在组件初始化时生效,后续currentPage变化不会触发表格分页状态更新,因为initialState不会响应props的变更。
修复方案
1. 修改CustomDataGrid组件:用paginationModel替代initialState
将initialState替换为paginationModel prop,这样当currentPage变化时,DataGrid会实时更新分页状态:
// 替换原来的initialState配置 paginationModel={{ pageSize: pageSize, page: currentPage - 1 }}
修改后的完整CustomDataGrid代码:
import { FC } from "react"; import { Paper, Stack, Typography } from "@mui/material"; import { DataGrid, GridToolbar, GridColDef } from "@mui/x-data-grid"; const CustomDataGrid: FC<{ tableTitle: string; rowsData: any; columnsData: GridColDef[]; currentPage: number; pageSize: number; getRowId?: (params: any) => any; error?: any; NoDataMsg: string; NoResultMsg: string; }> = ({ tableTitle, rowsData, columnsData, currentPage, pageSize, getRowId, error, NoDataMsg, NoResultMsg }) => { return ( <Paper elevation={4} style={{ marginBottom: "10px", borderRadius: "10px" }}> <Typography textAlign="center" variant="h5" style={{ paddingTop: "20px", paddingBottom: "40px", fontWeight: "bold" }} > {tableTitle} </Typography> <DataGrid columns={columnsData} rows={rowsData} rowHeight={64} // 使用paginationModel替代initialState paginationModel={{ pageSize: pageSize, page: currentPage - 1 }} ignoreDiacritics hideFooterPagination disableRowSelectionOnClick disableColumnFilter disableColumnMenu disableColumnSelector disableDensitySelector hideFooterSelectedRowCount getRowId={getRowId} autoHeight={true} slotProps={{ toolbar: { showQuickFilter: true } }} slots={{ toolbar: GridToolbar, noRowsOverlay: () => ( <Stack height="100%" alignItems="center" justifyContent="center"> <Typography variant="h4" sx={{ fontSize: "24px", color: error ? "error.main" : "primary.main" }} > { NoDataMsg } </Typography> </Stack> ), noResultsOverlay: () => ( <Stack height="100%" alignItems="center" justifyContent="center"> <Typography variant="h4" sx={{ fontSize: "24px", color: "primary.main" }}> { NoResultMsg } </Typography> </Stack> ) }} /> </Paper> ); }; export default CustomDataGrid;
2. 优化CustomPagination组件的onChange逻辑
原代码通过target.innerText获取页码的方式不可靠,MUI Pagination组件的onChange事件第二个参数直接返回当前选中的页码,直接使用该参数更稳定:
onChange={(e, value) => { setPage(value); }}
修改后的完整CustomPagination代码:
import { FC } from "react"; import { Pagination } from "@mui/material"; const CustomPagination: FC<{ page: number; setPage: (params: any) => any; totalRows: number; pageSize: number; }> = ({ page, setPage, pageSize, totalRows }) => { return ( <Pagination count={Math.ceil(totalRows / pageSize)} variant="outlined" shape="rounded" page={page} hideNextButton hidePrevButton size="small" sx={{ width: "100%" }} onChange={(e, value) => { setPage(value); }} /> ); }; export default CustomPagination;
效果说明
修改完成后,点击分页组件切换页码时,App中的page状态会更新,currentPage props传递给CustomDataGrid后,paginationModel会实时更新,DataGrid即可正确切换到对应页面。
内容的提问来源于stack exchange,提问作者user10033434
相关产品推荐
相关产品推荐

