import React, { useEffect, useReducer, useCallback } from 'react'import { Table } from 'antd';import { ArgTableProps, paginationInitialType, initialStateType, actionType } from './type'const useAsyncTable: React.FC<ArgTableProps> = props => {const { owncolumns, queryAction, params, baseProps } = props// 分页数据const paginationInitial: paginationInitialType = {current: 1,pageSize: 10,total: 0,}// table组件全量数据const initialState: initialStateType = {loading: false,pagination: paginationInitial,dataSource: []}const reducer = (state: initialStateType, action: actionType) => {const { payload } = actionswitch (action.type) {case 'TOGGLE_LOADING':return { ...state, loading: !state.loading }case 'SET_PAGINATION':return { ...state, pagination: payload.pagination }case 'SET_DATA_SOURCE':return { ...state, dataSource: payload.dataSource }default:return state}}const [state, dispatch] = useReducer(reducer, initialState)// 改变页码function handleTableChange(payload: any) {if (payload) {const { current } = payloaddispatch({type: 'SET_PAGINATION',payload: {pagination: {...state.pagination,current}}})}}// useCallback包装请求,缓存依赖,优化组件性能const fetchDataWarp = useCallback(fetchData,[params, state.pagination.current, owncolumns, queryAction],)async function fetchData() {dispatch({type: 'TOGGLE_LOADING'})// 分页字段名称转换const { current: indexfrom, pageSize: counts } = state.paginationlet res = await queryAction({ indexfrom, counts, ...params }).catch(err => {dispatch({ type: 'TOGGLE_LOADING' })return {}})// 关闭loadingdispatch({type: 'TOGGLE_LOADING'})if (res.result === 200) {const { totalcounts, list } = resdispatch({type: 'SET_PAGINATION',payload: {pagination: { ...state.pagination, total: totalcounts }}})// 回填list数据dispatch({type: 'SET_DATA_SOURCE',payload: {dataSource: list}})}}useEffect(() => {fetchDataWarp()}, [fetchDataWarp])return (<Tablecolumns={owncolumns(fetchData)}pagination={state.pagination}dataSource={state.dataSource}loading={state.loading}onChange={handleTableChange}{...baseProps}/>)}export default useAsyncTable
| 属性 | 类型 | 默认值 | 备注 |
|---|---|---|---|
| owncolumns | (updatefunc:Function): columns | 必选参数 | updatefunc用于刷新列表 |
| queryAction | (payload): Promise | 必选参数 | 用于列表数据获取 |
| baseProps | TableProps from antd | 任选 | antd的基础props |
| params | object | {} | 请求附加参数 |
const getColumn: getColumnType = updateMethod => {return [{title: "项目名称",dataIndex: "project_name",key: "project_name",},{title: '操作',key: 'setting',width: 200,render: (text: any, record: any, index: number) => {return (<div><Button type="primary" style={{ marginRight: '5px' }}>查看</Button><Popconfirmtitle="此操作将永久删除该项目, 是否继续?"okText="确定"cancelText="取消"onConfirm={() => {updateMethod()}}><Button type="danger">删除</Button></Popconfirm></div>)}}];}render(){return (<ArgTableowncolumns={updatefunc => getColumn(updatefunc)}queryAction={API.http_getProjectList}baseProps={{ rowKey: record => record.project_id }}params={searchData}/>)}
