使用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"
/>
)
}