skip to Main Content

When retrieving data with specified item amounts and offsets, a display issue occurs on the second page and subsequent pages.

For instance, on the first page, the data correctly shows the first 10 items. However, when using pagination to access the next set of items, only a different number of items is returned, despite the data fetched containing 10 items in the array:

https://codesandbox.io/s/listing-pokemon-on-datagrid-76w3v5

Fetching function:

const fetchPokemon = async (limit, offset) => {
  const response = await fetch(
    `https://pokeapi.co/api/v2/pokemon?limit=${limit}&offset=${offset}`
  );
  const data = await response.json();

  // this returns 10 items
  console.log(data);

  const returnedValues = {
    results: data.results,
    count: data.count
  };

  return returnedValues;
};

DataGrid component:

<DataGrid
    autoHeight
    columns={cols}
    loading={dataGridState.loading}
    rowCount={dataGridState.amount}
    rows={pokemon}
    pagination={{
      pageSize: dataGridState.pageSize,
      page: dataGridState.offset - 1
    }}
    pageSize={dataGridState.pageSize}
    onPageChange={handlePageSize}
    onPaginationModelChange={async (val) => handlePageSize(val)}
  />

enter image description here

2

Answers


  1. You are using server-side pagination, which means you are fetching the data from a remote source and handling the pagination logic on the server. So you need to pass the paginationMode prop with the value server to the DataGrid component. This tells the component that it should not handle the pagination internally, but delegate it to the server.

    For example:

    <DataGrid
      {...restProps}
      paginationMode="server"
    />
    

    You can see the whole example here: codesandbox.io.

    To learn more, please see Server Side Pagination Docs.

    According to this documentation:

    • Set the prop paginationMode to server
    • Provide a rowCount prop to let the data grid know how many pages there are
    • Use the onPaginationModelChange prop callback to load the rows when the page changes

    PS: You’re using dataGridState.offset as page. It’s wrong.
    Instead, you need to use dataGridState.offset / dataGridState.pageSize + 1 as page.

    Login or Signup to reply.
  2. Server-side pagination

    By default, the pagination is handled on the client. This means you have to give the rows of all pages to the grid. If your dataset is too big, and you only want to fetch the current page, you can use server-side pagination.

    Set the prop paginationMode to 'server'

    import * as React from 'react';
    import { useAsyncEffect, useReactive } from 'ahooks';
    import Box from '@mui/material/Box';
    import { DataGrid } from '@mui/x-data-grid';
    
    const cols = [
        {
            field: 'name',
            headerName: 'Name',
            flex: 1,
        },
    ];
    
    export default function ColumnSpanningFunction() {
        const [pokemon, setPokemon] = React.useState([]);
    
        const dataGridState = useReactive({
            amount: 0,
            pageSize: 10,
            offset: 0,
            page: 0,
        });
    
        const refresh = async () => {
            console.log('refresh is being used');
            const returnedValues = await fetchPokemon(dataGridState.pageSize, dataGridState.offset);
    
            const changed = returnedValues.results.map((value, id) => {
                return { ...value, id: value.url };
            });
            dataGridState.amount = returnedValues.count;
            setPokemon(changed);
        };
    
        const onPageChange = (newPage) => {
            console.log('newPage: ', newPage);
            dataGridState.offset = newPage * dataGridState.pageSize;
            dataGridState.page = newPage;
            refresh();
        };
    
        useAsyncEffect(async () => {
            await refresh();
        }, []);
    
        return (
            <Box sx={{ width: '100%' }}>
                <DataGrid
                    autoHeight
                    columns={cols}
                    rowCount={dataGridState.amount}
                    rows={pokemon}
                    pagination
                    paginationMode="server"
                    page={dataGridState.page}
                    pageSize={dataGridState.pageSize}
                    rowsPerPageOptions={[dataGridState.pageSize]}
                    onPageChange={onPageChange}
                />
            </Box>
        );
    }
    
    const fetchPokemon = async (limit, offset) => {
        const response = await fetch(`https://pokeapi.co/api/v2/pokemon?limit=${limit}&offset=${offset}`);
        console.log('one fetchPokemon | limit: ', limit, ' | offset: ', offset);
        const data = await response.json();
        console.log(data);
        return {
            results: data.results,
            count: data.count,
        };
    };
    

    codesandbox

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search