【React】二次封装Antd的Table组件

使用Table并不难,但是每次使用都会伴随着很大一部分逻辑,如loding效果、表格分页筛选排序、调接口完毕后赋值等等,使用方法基本一致,所以可以将他们二次封装,从而减少代码量,提升代码可读性。

二次封装表格

import { Table, TableProps } from "antd"
import { useFetchTableData } from "./useFetchTableData"
import { useMemo } from "react"

type Props = {
  dataKey?: string 
  fetchMethod: (params: {}) => Promise<any>
  requestParam: { size: number; search: {}[] }
  onParamChange: (data: any) => void
  [key: string]: any 
}

interface DataType {}

const BasicTable = ({
  dataKey = "data_list", // 接口响应中list对应的key
  fetchMethod,
  requestParam,
  onParamChange,
  ...resetTableProps
}: Props) => {

  const memoParams = useMemo(() => {
    return { ...requestParam }
  }, [requestParam]) // 避免值类型一样的对象,触发两次请求
  
  // 请求表格数据
  const { loading, tableData } = useFetchTableData(fetchMethod, memoParams)

  const onTableChange: TableProps<DataType>["onChange"] = (
    { current, pageSize }, // 分页
    filters, // 筛选
    _sorter, // 排序
    extra // 当前table数据 以及 当前行为
  ) => {
    let params
    if (extra.action === "filter") {
      // 触发筛选,修改search
      let search = []
      for (let key in filters) {
        if (filters[key]) {
          search.push({ [key]: filters[key] })
        }
      }
      params = { ...requestParam, page: current, size: pageSize, search }
    } else {
      params = {
        ...requestParam,
        page: current,
        size: pageSize,
      }
    }

    onParamChange(params)
  }

  return (
    <Table
      bordered
      onChange={onTableChange}
      loading={loading}
      dataSource={tableData[dataKey]}
      pagination={{
        total: tableData.total_count,
        showSizeChanger: false,
        current: tableData.page,
        pageSize: requestParam.size,
        showTotal: (t) => <span>{t}</span>,
      }}
      {...resetTableProps}
    />
  )
}
export default BasicTable

请求相关

import { message } from "antd"
import { useEffect, useState } from "react"

interface TableData {
  [key: string]: any // 允许任意字符串作为键,值的类型是 any
  data_list: any[]
  total_count: number
  page: number
}
interface Response {
  code: number
  message: string
  data: any
}

export function useFetchTableData(
  fetchMethod: (params: {}) => Promise<any>,
  parameter: {}
) {
  const [loading, setLoading] = useState(false)
  const [tableData, setTableData] = useState<TableData>({
    data_list: [],
    total_count: 0,
    page: 1,
  })

  // 获取表格数据
  async function fetchTableData() {
    try {
      setLoading(true)
      const res: Response = await fetchMethod(parameter)

      if (res.code === 1) {
        setTableData(res.data)
      } else {
        message.warning(res.message)
      }
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    fetchTableData()
  }, [parameter])

  return { loading, tableData }
}

使用

interface DataType {
	...
}
const columns: ColumnsType<DataType> = [...]

export default () => {
  const getList = async (params) => {
    // 发送请求并将响应res返回
    return res
  }
  const [requestParam, setParameter] = useState({
    page: 1,
    size: 10,
    search: [],
    start_time: "",
    end_time: "",
  })
  const memoParameter = useMemo(() => ({ ...requestParam }), [requestParam])

  return (
    <BasicTable
      dataKey="data" // 这里写data意味着dataSource使用调用接口返回的res.data.data,不写这行默认为res.data.data_list,可根据需求自行更改
      fetchMethod={getUserlist}
      requestParam={memoParameter}
      onParamChange={(data: any) => {
        setParameter({ ...requestParam, ...data })
      }}
      // 下面的都会被剩余参数接收
      columns={columns}
      rowKey="id"
    />
  )
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

田本初

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值