Search code examples
reactjsscrollantd

Scrolling pages in Ant Design tables


I have a table from ANTD and it has many pages, since I have defined pagination for it, I want it to be possible to scroll as well, and go to the next page when the user scrolls to the bottom of the table.

this is my component:

 <Table columns={columns} dataSource={filteredData}
                title={() => <>  <h3>title</h3>}
                rowClassName="rowClassName"
                pagination={{
                    onChange: cancel,
                }}
            />

How can I do it?


Solution

  • Check if the scrollable container .ant-table-body reaches the bottom, if the scrollbar reaches the bottom, go to the next page. After the pagination changes, scroll the scrollable container to the top.

    import React, { useEffect, useLayoutEffect, useState } from 'react';
    import './index.css';
    import { Table } from 'antd';
    import type { TableColumnsType } from 'antd';
    
    interface DataType {
      key: React.Key;
      name: string;
      age: number;
      address: string;
    }
    
    const columns: TableColumnsType<DataType> = [
      {
        title: 'Name',
        dataIndex: 'name',
        width: 150,
      },
      {
        title: 'Age',
        dataIndex: 'age',
        width: 150,
      },
      {
        title: 'Address',
        dataIndex: 'address',
      },
    ];
    
    const data: DataType[] = [];
    for (let i = 0; i < 100; i++) {
      data.push({
        key: i,
        name: `Edward King ${i}`,
        age: 32,
        address: `London, Park Lane no. ${i}`,
      });
    }
    
    function calculatePage(pageSize: number, total: number) {
      return Math.floor((total - 1) / pageSize) + 1;
    }
    
    const allPage = calculatePage(10, data.length);
    
    const App: React.FC = () => {
      const [pagination, setPagination] = useState({ current: 1, pageSize: 10 });
    
      useEffect(() => {
        const $tableBody = document.querySelector('.ant-table-body');
        const onScroll = () => {
          if (
            Math.abs(
              $tableBody.scrollHeight -
                $tableBody.scrollTop -
                $tableBody.clientHeight
            ) < 1
          ) {
            console.log('reach bottom');
            if (pagination.current < allPage) {
              setPagination((pre) => ({ ...pre, current: pre.current + 1 }));
            }
          }
        };
        if ($tableBody) {
          $tableBody.addEventListener('scroll', onScroll);
        }
    
        return () => {
          if ($tableBody) {
            $tableBody.removeEventListener('scroll', onScroll);
          }
        };
      }, [pagination]);
    
      // scroll to top when pagination changes
      useLayoutEffect(() => {
        const $tableBody = document.querySelector('.ant-table-body');
        if ($tableBody) {
          $tableBody.scrollTop = 0;
        }
      }, [pagination]);
    
      return (
        <Table
          columns={columns}
          dataSource={data}
          total={data.length}
          pagination={pagination}
          onChange={(pagination) => {
            setPagination(pagination);
          }}
          scroll={{ y: 240 }}
        />
      );
    };
    
    export default App;
    

    stackblitz