reactjsmui-x-data-grid

setPage doesn't change the page in mui datagrid


The setPage is working fine in the pagination component. However, it doesn't change the page in the datagrid itself. I can see the number changes (page) in the browser console.

If a entered the page number statically in the useState, it correctly displays the page.

Here's my code:

datagrid component:

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;

pagination component:

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

Solution

  • MUI's datagrid pagination mentions using apiRef.

    That ref will then provide the correct setPage callback via useImperativeHandle for which that ref is required.

    So then, instead of calling

    <Button onClick={() => setPage(1)}>Click me</Button>
    

    you would instead do

    <Button onClick={() => apiRef.current.setPage(1)}>Click me</Button>
    

    Also, you need to pass the correct prop, and not have it just randomly placed outside of the component, like this

    slots={{
      pagination: YourCustomPaginationComponent
    }}