Search code examples
reactjsantd

how create a reusable antd table react


I am using antd react framework and I have many components rendering antd table with pagination and sorting, so I decided to make a reusable table I don't want to repeat myself every time I need a table in the below implementation I successfully loaded the table, but pagination and sorting are not working properly can anyone help me please,

here is what i tried reusable table component (useTable.jsx) :-

import { Table } from 'antd';
import React, { useEffect, useState } from 'react';

export function useTable(columns, data, fetchData, loading) {
  

  const handleTableChange = (newPagination, filters, sorter) => {
    fetchData({
      sortField: sorter.field,
      sortOrder: sorter.order,
      pagination: newPagination,
      ...filters,
    });
  };

  const TableContainer = () => (
    <Table columns={columns} dataSource={data} loading={loading} onChange={handleTableChange} />
  );
  return { TableContainer };
}

parent component using the table:-

import React, { useEffect, useState } from 'react';
import qs from 'qs';
import { Table, Card, Button, Input, Space } from 'antd';
import styles from './Class.less';
import { useTable } from '../../../components/common/useTable';
const columns = [
  {
    title: 'Name',
    dataIndex: 'name',
    sorter: true,
    render: (name) => `${name.first} ${name.last}`,
    width: '20%',
  },
  {
    title: 'Gender',
    dataIndex: 'gender',
    filters: [
      {
        text: 'Male',
        value: 'male',
      },
      {
        text: 'Female',
        value: 'female',
      },
    ],
    width: '20%',
  },
  {
    title: 'other',
    dataIndex: 'other',
    sorter: true,
  },

  {
    title: 'Action',
    dataIndex: 'email',
    render: () => (
      <Space>
        <a color="yellow" onClick={() => alert('edit')}>
          Edit
        </a>
        <a color="yellow" onClick={() => alert('delete')}>
          Delete
        </a>
      </Space>
    ),
  },
];

const getRandomuserParams = (params) => ({
  results: params.pagination?.pageSize,
  page: params.pagination?.current,
  ...params,
});
const Classes = () => {
  const [data, setData] = useState();
  const [loading, setLoading] = useState(false);
  const [pagination, setPagination] = useState({
    current: 1,
    pageSize: 10,
  });

  const fetchData = (params = {}) => {
    setLoading(true);
    fetch(`https://randomuser.me/api?${qs.stringify(getRandomuserParams(params))}`)
      .then((res) => res.json())
      .then(({ results }) => {
        setData(results);
        setLoading(false);
        setPagination({
          ...params.pagination,
          total: 200, // 200 is mock data, you should read it from server
          // total: data.totalCount,
        });
      });
  };

  const { TableContainer } = useTable(columns, data, fetchData, loading);

  useEffect(() => {
    fetchData({
      pagination,
    });
  }, []);

  return (
    <Card className={styles.card}>
      <TableContainer
        columns={columns}
        rowKey={(record) => record.login.uuid}
        dataSource={data}
        loading={loading}
      />
    </Card>
  );
};

export default Classes;

Thanks!


Solution

  • I figured out by my own and here is my solution

    export function useTable(columns, data) {
      const [page, setPage] = useState(1);
    
      const handlePageChange = (newpage) => {
        setPage(newpage);
      };
    
      const TableContainer = ({ loading }) => (
        <Table
          columns={columns}
          dataSource={data}
          pagination={{
            current: page,
            pageSize: 6,
            total: data?.length,
            onChange: (page) => handlePageChange(page),
            size: 'medium',
          }}
          loading={loading}
        />
      );
      return { TableContainer };
    

    }

    my component:-

     return (
        <Card className={styles.card}>
          <TableContainer columns={columns} rowKey={(record) => record.login.uuid} dataSource={data} />
        </Card>
      );