react+ts+hook封裝一個table分頁組件(建議收藏,直接使用)
# 前言
> 大家好 我是歌謠 我是一名堅持寫博客四年的博主 最好的種樹是十年前
> 其次是現(xiàn)在,今天繼續(xù)對ant design table的分頁封裝進行講解
??
# 封裝準(zhǔn)備(多看官網(wǎng))
## jsx風(fēng)格的api
```
? <>
? ? <Table<User> columns={columns} dataSource={data} />
? ? /* 使用 JSX 風(fēng)格的 API */
? ? <Table<User> dataSource={data}>
? ? ? <Table.Column<User> key="name" title="Name" dataIndex="name" />
? ? </Table>
? </>
```
??
## 模擬jsx的api結(jié)構(gòu)
??
```
? <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>
```
### 分頁參數(shù)官方api
??
```
?<Pagination
? ? ? total={85}
? ? ? showTotal={(total, range) => `${range[0]}-${range[1]} of ${total} items`}
? ? ? defaultPageSize={20}
? ? ? defaultCurrent={1}
? ? />
```


### 解析
??
> rowKey表示唯一標(biāo)識 區(qū)當(dāng)前行的id
> resetProps表示剩余參數(shù)
??
### onTableChange回調(diào) 子傳父
??
```
const onTableChange = useCallback((pageParams: PaginationProps) => {
? ? ? ? setPagination(pageParams);
? ? ? ? props.onChange(pageParams);
? ? }, []);
```
??
> 把分頁參數(shù)傳給父級
??
## ts限定
??
```
interface BaseTableProps<T> extends TableProps<T> {
? ? data: {
? ? ? ? list: T[];
? ? ? ? page: PageResponseData;
? ? };
? ? children: React.ReactNode;
? ? onChange: (page: PaginationProps) => void;
}
```

## 默認(rèn)狀態(tài)
??
```
? 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="設(shè)備類型" 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="設(shè)備名稱" dataIndex="name" align="center"></Table.Column>
? ? ? ? ? ? ? ? <Table.Column<Menu> title="設(shè)備編碼" 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>
```
## 解析
>? 子傳父分頁回調(diào)
??
```
? const onTableChange = useCallback(({ current, pageSize }: PaginationProps) => {
? ? ? ? setPage({ pageIndex: current as number, pageSize: pageSize as number });
? ? }, []);
```
??
> loading表格是否渲染完成
??
??
## 演示結(jié)果

??
## 總結(jié)
??
> 歌謠出品 必是精品 微信公眾號關(guān)注前端小歌謠 帶你進入巔峰人才交流群