如何封装通用型Table分页组件并自定义相关Hook

| 483字 | 2分钟

背景

日常开发中,我们再对一个 Table 进行分页处理的过程时,虽然 AntD Table 已经为我们做了很多的处理。 AntD Table 但是各种 onChange 事件到处都是,导致每个页面有这种Table分页功能的话,每次都要重复写好多。

hooks-202203191540273.png

获取pageSize/currentPage/total/...每次都要定义一遍来获取对应的值,这样无疑要维护很多的 useState

const [pageSize, setPageSize] = useState(10);
const [currentPage, setCurrentPage] = useState(1);
const [total, setTotal] = useState(10);
...

其实完全可以封装一个专门处理page分页的 hooks 封装前,我们先要知道我们需要处理哪些数据?

如下这些是 Table 必须的值:
currentPage、setCurrentPage、pageSize、setPageSize、total、setTotal
onChange、onShowSizeChange、resetPage


如何封装

import { useState } from 'react';
const DEFAULT_CURRENT_PAGE = 1;
const DEFAULT_PAGE_SIZE = 10;
const DEFAULT_TOTAL = 10;

export default function (): {
  currentPage: number;
  pageSize: number;
  total?: number;
  setPageSize(pageSize: number): void;
  setCurrentPage(currentPage: number): void;
  onChange(currentPage: number, pageSize?: number | undefined): void;
  onShowSizeChange(currentPage: number, pageSize: number): void;
  resetPage(): void;
  setTotal(total: number): void;
} {
  const [pageSize, setPageSize] = useState<number>(DEFAULT_PAGE_SIZE);
  const [currentPage, setCurrentPage] = useState<number>(DEFAULT_CURRENT_PAGE);
  const [total, setTotal] = useState<number>(DEFAULT_TOTAL);

  // 获取对应的分页及每页数据
  const onChange = (currentPage: number, pageSize: number) => {
    setPageSize(pageSize);
    setCurrentPage(currentPage);
  };

  const onShowSizeChange = (currentPage: number, pageSize: number) => {
    setPageSize(pageSize);
    setCurrentPage(DEFAULT_CURRENT_PAGE);
  };

  // 重置分页数据
  const resetPage = () => {
    setPageSize(DEFAULT_PAGE_SIZE);
    setCurrentPage(DEFAULT_CURRENT_PAGE);
  };

  return {
    pageSize,
    currentPage,
    setPageSize,
    setCurrentPage,
    onChange,
    onShowSizeChange,
    resetPage,
    total,
    setTotal,
  };
}

如何使用

import { useEffect } from 'react';
import usePageHooks from '../pageHooks'; // 从对应文件引入pageHooks组件
const {
  pageSize,
  currentPage,
  onChange,
  onShowSizeChange,
  total,
  setTotal
} = usePageHooks();

// 页面初始化,默认拿到table有多少条数据
useEffect(() => {
  setTotal(data.length); 
},[]);

<Table
  columns={columns}
  dataSource={data}
  pagination={{
    pageSize,
    current: currentPage,
    showQuickJumper: true,
    showSizeChanger: true,
    onChange,
    onShowSizeChange,
    total,
    showTotal: (total: number, range: number[]) => 
      `第 ${range[0]}-${range[1]} 条 / 共 ${total} 条`,
  }}
/>

小结

通过 pageHooks 组件,我们就完成了一个通用 table 分页功能.
这样每个页面就不需要再单独维护 pageSize, currentPage, ... 这些 useState.