You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 10:55:54