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...

感谢老铁的三连🤞

相关推荐
泯泷26 分钟前
手搓JSVMM第 8 篇:函数调用:参数、返回值与调用帧
前端·javascript·前端框架
Sherotree1 小时前
Google Antigravity——Agent 被提到主界面
前端·ide·后端·edge浏览器
里欧跑得慢1 小时前
Flutter 像素级还原:设计稿到代码的视觉无损转换技巧
前端·css·flutter·web
里欧跑得慢2 小时前
Flutter 三方库 function_tree — 鸿蒙应用开发中的动态数学公式解析与计算神器,实现鸿蒙深度适配下的复杂函数逻辑运行时求值实战(适配鸿蒙 HarmonyOS Next ohos)
android·前端·安全·flutter·华为·harmonyos
苏灿烤鱼2 小时前
没有机密文件,也没有付费数据,在浏览器里造一颗"间谍卫星"
前端·javascript·github
泯泷3 小时前
手搓JSVM第 5 篇:写第一个编译器:从 AST 生成 IR
前端·javascript·算法
泯泷3 小时前
手搓JSVM第 7 篇:控制流:if、while 与 jump
前端·javascript·算法
泯泷3 小时前
手搓JSVM第 6 篇:把 IR 编成字节码:emit 与 label fixup
前端·javascript·算法
泯泷3 小时前
手搓JSVM第 3 篇:从栈式 VM 到寄存器式 VM:为什么我们选择寄存器
前端·javascript·算法
泯泷3 小时前
第 4 篇:让 VM 支持变量:Slot、Environment 与 TDZ
前端·javascript·算法