支持搜索的自定义表格hooks

312 阅读1分钟

自定义hooks会处理当前页码数据、数据总数、翻页器相关参数、loading状态,简化业务中使用逻辑,只需关注搜索参数的变化即可。

自定义hooks

import { useState, useEffect, useRef } from "react";

export interface UseTableParams {
  requestFunc: Function, // 请求数据的方法
  initRequest?: Boolean, // 是否要初始请求
  initPageSize: number, // 每页展示的初始数据
  searchParams?: any, // 搜索相关的请求参数
}

export const useTable = ({
  requestFunc,
  initRequest = true,
  initPageSize,
  searchParams,
}: UseTableParams) => {
  const hasFirstRender = useRef(false); // 是否已经完成第一次render
  const [page, setPage] = useState(1); // 页码
  const [limit, setLimit] = useState(initPageSize); // 每页展示的数量
  const [loading, setLoading] = useState(false); // 数据是否请求中
  const [data, setData] = useState([]); // 表格数据
  const [totalCount, setTotalCount] = useState(0); // 数据总数

  // 获取表格数据
  const getData = async(newParams?: any) => {
    try {
      const requestParams = {
        page,
        limit,
        ...searchParams,
        ...newParams,
      };
      setLoading(true);
      const res = await requestFunc(requestParams);
      setPage(requestParams.page);
      setLimit(requestParams.limit);
      setData(res.data?.data || []);
      setTotalCount(res.data?.count || 0);
      setLoading(false);
    } catch (error) {
      setLoading(false);
    }
  }

  // 需要初始请求时,第一次render请求数据
  useEffect(() => {
    initRequest && getData();
  }, []);

  // 监听搜索参数的变化重新请求数据
  useEffect(() => {
    if (hasFirstRender.current) {
      getData({ page: 1 });
    } else {
      hasFirstRender.current = true;
    }
  }, [searchParams]);

  // 翻页器信息改变重新获取数据
  const onPageChange = (newPage: number, newLimit: number) => {
    const newPageNum = newLimit !== limit ? 1 : newPage;
    getData({
      page: newPageNum,
      limit: newLimit
    })
  }

  return {
    page, // 页码
    limit, // 每页显示的数量
    loading, // 接口是否请求中
    data, // 数据
    totalCount, // 数据总数
    onPageChange, // 翻页器相关修改的方法
    getData, // 获取数据的方法
  }
}

使用

以antd的组件为例。

const [searchParams, setSearchParams] = useState({
  type: ['4', '3'],
}); // 搜索相关的参数

const { page, limit, loading, data, totalCount, onPageChange, getData } = useTable({
  requestFunc: driveVideoRequest,
  initRequest: true,
  initPageSize: 40,
  searchParams,
});

// 重新获取数据
const reloadData = () => {
  getData();
}

// 搜索(修改搜索的参数之后,自定义hooks会自动根据新的搜索参数获取新的数据)
const onSearch = (values: any) => {
  setSearchParams(values);
};

// 表单搜索
<Form onFinish={onSearch}>
  ...
</Form>

// 重新获取数据
<Button onClick={reloadData}>重新获取数据</Button>

// 表格展示数据
<Table
  dataSource={data}
  pagination={{
    total: totalCount,
    current: page,
    pageSize: limit,
    onChange: onPageChange,
  }}
  loading={loading}
/>