Antd table 请求这样写代码少一半

前言

最近在重构 Open-Job 的前端项目时发现,项目中有多处用到了 Antd 的 table 组件,而且都还是分页的,这些分页请求的逻辑还都差不多,只有请求的接口不一样,所以就会产生很多重复的代码,例如下面这样

重复代码块

tsx 复制代码
const TableList: React.FC = () => {
    const [loading, setLoading] = useState(false);
    const [tableData, setTableData] = useState([]);
    const [tableParams, setTableParams] = useState<TableParams>({
    pagination: {
      current: 1,
      pageSize: 10,
    },
  });
  
  const fetchData = async () => {
    setLoading(true);
    try {
      const response: any = await fetchDataPage({
        current: tableParams.pagination?.current,
        pageSize: tableParams.pagination?.pageSize,
      });

      setTableData(response?.records);
      setTableParams({
        ...tableParams,
        pagination: {
          ...tableParams.pagination,
          total: response.total,
        },
      });
    } catch (error) {
      message.error('服务繁忙,请稍后重试');
    } finally {
      setLoading(false);
    }
  };
}

上面提到的 TableParams 结构如下,其中 fetchDataPage 就是我们请求的后端分页接口。

ts 复制代码
export interface TableParams {  
    pagination?: TablePaginationConfig;  
    order?: any;  
    filters?: Record<string, FilterValue>;  
}

那如果我们有多个这样的操作,就会产生很多重复的代码,其中只有后端接口是不一样的,那接下来我们就来优化下.

定义分页请求钩子函数

这里,我定义了一个分页请求钩子函数,源码在最后

ts 复制代码
import { useEffect, useState } from 'react';  
import { message, TablePaginationConfig } from 'antd';  
import { PageQuery, PageResult } from '@/lib/request';  
import { TableParams } from '@/types/typings';  
  
/**  
* antd table 分页请求钩子函数
*  
* <p>  
* @param request 你的数据请求 api  
* @return [  
*     data:table 数据,  
*     loading: 加载状态,  
*     tableParams:分页参数,  
*     onTableChange:切换分页事件,  
*     fetchData:方便外部主动触发数据加载  
* ]  
* </p>  
*  
*/  
const usePaginationRequest = <T>(  
    request: (params: PageQuery) => Promise<PageResult<T>>  
): [  
    T[],  
    boolean,  
    TableParams,  
    (pagination: TablePaginationConfig) => void,  
    () => Promise<void>,  
] => {  
    const [data, setData] = useState<T[]>([]);  
    const [loading, setLoading] = useState(false);  
    const [tableParams, setTableParams] = useState<TableParams>({  
        pagination: {  
            current: 1,  
            pageSize: 10,  
        },  
    });  
  
    const fetchData = async () => {  
        setLoading(true);  
        try {  
            const response: PageResult<T> = await request({  
                current: tableParams.pagination?.current,  
                pageSize: tableParams.pagination?.pageSize,  
            });  

            setData(response?.records);  
            setTableParams({  
                ...tableParams,  
                pagination: {  
                    ...tableParams.pagination,  
                    total: response.total,  
                },  
            });  
        } catch (error) {  
            message.error('服务繁忙,请稍后重试');  
        } finally {  
            setLoading(false);  
        }  
    };  

    const onTableChange = (pagination: TablePaginationConfig) => {  
        setTableParams({  
            pagination,  
        });  

        // `dataSource` is useless since `pageSize` changed  
        if (pagination.pageSize !== tableParams.pagination?.pageSize) {  
            setData([]);  
        }  
    };  

    useEffect(() => {  
        fetchData().then();  
    }, [JSON.stringify(tableParams)]);  

    return [data, loading, tableParams, onTableChange, fetchData];  
};  
  
export default usePaginationRequest;

使用分页请求钩子函数

tsx 复制代码
const JobTableList: React.FC = () => {  
   
    const request = async (params: PageParams) => {  
        return await fetchDataPage({  
            current: params.current,  
            pageSize: params.pageSize,  
        });  
    };  
  
    const [tableData, loading, tableParams, onTableChange, fetchData] =  
    usePaginationRequest<OpenJob>((params) => request(params));
}

这样代码是不是少了很多,这样我们在其他地方就只需要像上面这样写少量的代码就可以实现分页请求了,是不是很爽。

这时,如果你需要在请求时添加其他参数,那就可以像下面这样处理啦,非常的简单。

tsx 复制代码
const JobTableList: React.FC = () => {  
    const [form] = Form.useForm();  
    
    const request = async (params: PageParams) => {  
        const values = await form.validateFields();  
        return await fetchDataPage({  
            ...values,  
            current: params.current,  
            pageSize: params.pageSize,  
        });  
    };  
  
    const [tableData, loading, tableParams, onTableChange, fetchData] =  
    usePaginationRequest<OpenJob>((params) => request(params));
}

项目地址: github.com/lijunping36...

感谢老铁的三连🤞

相关推荐
Sakura_j_h_1 分钟前
Three.js 单文件离线机械臂工作台:爆炸图、透明外壳与剖面
前端·机械臂·webgl·three.js·1024程序员节·esbuild
DisonTangor22 分钟前
MOSS-Image-Base 实战:从文生图到 JSON 布局精准控图
人工智能·ai作画·开源·aigc·1024程序员节
舰长11528 分钟前
将百万数据插入到 Redis,有哪些实现方案?
数据结构·redis·开源
分布式存储与RustFS1 小时前
机器要下线,数据先线上搬家:RustFS 存储池退役实操
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
计算机魔术师2 小时前
管谷歌的不是Pichai一个人,是一整层AI智能体
前端
米米商聊2 小时前
图标能点,按钮就可用了吗?键盘、名称与收藏状态
前端·javascript
Younglina2 小时前
三个晚上,我和 WorkBuddy 做了个生图网站
前端·后端·ai编程
xy34532 小时前
Axure 9.0 内联框架加载方式
前端·ui·html·axure·原型·产品设计
35岁程序员的自救之路3 小时前
10个开源免费的社区系统推荐
开源
陈随易3 小时前
副业搞钱点子之收入查看器
前端·后端