react+ts+hook封装一个table分页组件(建议收藏,直接使用)

175 阅读2分钟

前言

大家好 我是歌谣 我是一名坚持写博客四年的博主 最好的种树是十年前

其次是现在,今天继续对ant design table的分页封装进行讲解

封装准备(多看官网)

jsx风格的api


  <>

    <Table<User> columns={columns} dataSource={data} />

    /* 使用 JSX 风格的 API */

    <Table<User> dataSource={data}>

      <Table.Column<User> key="name" title="Name" dataIndex="name" />

    </Table>

  </>

模拟jsx的api结构


  <Card style={{ marginTop: '24px' }}>

            <Table<any>

                {...resetProps}

                onChange={onTableChange}

                dataSource={list}

                rowKey={record => `${record.id}`}

                pagination={{

                   

                    pageSizeOptions: ['5', '10', '20', '50'],

                    ...pagination,

                    total: page.dataTotal,

                    showTotal: () => {

                        return '共 ' + page.dataTotal + ' 条记录';

                    },

                }}

            >

                {props.children}

            </Table>

        </Card>

分页参数官方api


 <Pagination

      total={85}

      showTotal={(total, range) => `${range[0]}-${range[1]} of ${total} items`}

      defaultPageSize={20}

      defaultCurrent={1}

    />

在这里插入图片描述

在这里插入图片描述

解析

rowKey表示唯一标识 区当前行的id

resetProps表示剩余参数

onTableChange回调 子传父


const onTableChange = useCallback((pageParams: PaginationProps) => {

        setPagination(pageParams);

        props.onChange(pageParams);

    }, []);

把分页参数传给父级

ts限定


interface BaseTableProps<T> extends TableProps<T> {

    data: {

        list: T[];

        page: PageResponseData;

    };

    children: React.ReactNode;

    onChange: (page: PaginationProps) => void;

}

在这里插入图片描述

默认状态


  const {

        data: { list, page },

        ...resetProps

    } = props;

  


    const [pagination, setPagination] = useState<PaginationProps>({

        defaultCurrent: 1,

        defaultPageSize: 10,

        showSizeChanger: true,

    });

总体封装代码


import React, { useCallback, useState } from 'react';

import { Table,Card } from 'antd';

import { PaginationProps } from 'antd/lib/pagination';

import { TableProps } from 'antd/lib/table';

import { PageResponseData } from './type';

import {isHKCard} from "@/utils/regexp";

import { type } from 'os';

  


interface BaseTableProps<T> extends TableProps<T> {

    data: {

        list: T[];

        page: PageResponseData;

    };

    children: React.ReactNode;

    onChange: (page: PaginationProps) => void;

}

const BasicTable: React.FC<any> = (props: BaseTableProps<any>) =>{

// function BasicTable<T extends { id?: number }>(props: BaseTableProps<T>) {

    const {

        data: { list, page },

        ...resetProps

    } = props;

  


    const [pagination, setPagination] = useState<PaginationProps>({

        defaultCurrent: 1,

        defaultPageSize: 10,

        showSizeChanger: true,

    });

  


    const onTableChange = useCallback((pageParams: PaginationProps) => {

        setPagination(pageParams);

        props.onChange(pageParams);

    }, []);

  


    return (

        <Card style={{ marginTop: '24px' }}>

            <Table<any>

                {...resetProps}

                onChange={onTableChange}

                dataSource={list}

                rowKey={record => `${record.id}`}

                pagination={{

                   

                    pageSizeOptions: ['5', '10', '20', '50'],

                    ...pagination,

                    total: page.dataTotal,

                    showTotal: () => {

                        return '共 ' + page.dataTotal + ' 条记录';

                    },

                }}

            >

                {props.children}

            </Table>

        </Card>

    );

}

  


export default BasicTable;

  


使用方法


  <BasicTable data={menuData} onChange={onTableChange} loading={loading}>

                <Table.Column<Menu> title="设备类型" dataIndex="machineTypeName" align="center"

                 render={(text, record:any, index) => (

                    <span>{record?.t_device_machine_type?.machine_type_name}</span>

                )}

                ></Table.Column>

                <Table.Column<Menu> title="设备名称" dataIndex="name" align="center"></Table.Column>

                <Table.Column<Menu> title="设备编码" dataIndex="code" align="center"></Table.Column>

                <Table.Column<Menu>

                    title="添加时间"

                    dataIndex="register_date"

                    align="center"

                    render={(text, record, index) => (

                        <span>{countFormat(text)}</span>

                    )}

                ></Table.Column>

                <Table.Column<Menu>

                    title="修改时间"

                    dataIndex="update_date"

                    align="center"

                    render={(text, record, index) => (

                        <span>{countFormat(text)}</span>

                    )}

                ></Table.Column>

                <Table.Column<Menu>

                    title="操作"

                    align="center"

                    render={(text, record, index) => (

                        <MenuButton index={index} record={record} onButtonClick={onButtonClick} />

                    )}

                ></Table.Column>

            </BasicTable>

解析

 子传父分页回调


  const onTableChange = useCallback(({ current, pageSize }: PaginationProps) => {

        setPage({ pageIndex: current as number, pageSize: pageSize as number });

    }, []);

loading表格是否渲染完成

演示结果

在这里插入图片描述

总结

歌谣出品 必是精品 微信公众号关注前端小歌谣 带你进入巅峰人才交流群