import { ListProps, TableProps } from 'antd'; import { useState, useRef, useEffect } from 'react'; import { PageResult, SearchOption } from '../../service/def'; type TableState = { data: T[]; total: number; loading: boolean; pageSize: number; pageNumber: number; search: { [key: string]: string }; sort?: [string, 'asc' | 'desc']; } export type PageTableContext = { tableProps: TableProps, listProps?: ListProps, search: (params?: SearchOption) => void, refresh: () => void } function usePageTable( service: (params?: SearchOption) => Promise>, options: SearchOption = {} ): PageTableContext { // 写在一起避免异步之后多次setState导致多次重绘 const [state, setState] = useState>(() => ({ data: [], total: 0, loading: false, pageSize: options.pageSize ?? 10, pageNumber: options.pageNumber ?? 1, sort: options.sort, search: options.search || {}, })); const abort = useRef(false); useEffect(() => { abort.current = false; search(); return () => { abort.current = true; } }, []); const search = (opt: SearchOption = {}) => { setState(s => ({ ...s, loading: true })); const pageParams = { pageNumber: opt?.pageNumber ?? state.pageNumber, pageSize: opt?.pageSize ?? state.pageSize, sort: opt?.sort ?? state.sort, search: opt?.search ?? state.search, }; service(pageParams).then((data) => { if (!abort.current) { setState({ ...pageParams, data: data.list, total: data.totalRow, loading: false, }) } }); } const handleTableChange = (pagination: any, filters: any, sort: any) => { search({ pageNumber: pagination.current, pageSize: pagination.pageSize, sort }); } let listProps = undefined; if (false) { const handleListChange = (page: number, pageSize: number) => { search({ pageNumber: page, pageSize: pageSize }); } listProps = { dataSource: state.data, loading: state.loading, pagination: { showTotal: (totalRow: any) => `共${totalRow}条`, showSizeChanger: true, showQuickJumper: true, pageSize: state.pageSize, current: state.pageNumber, total: state.total, pageSizeOptions: ['10', '20', '50', '100'], onChange: handleListChange } } } return { tableProps: { size: 'small', bordered: true, dataSource: state.data, pagination: { showTotal: (totalRow: any) => `共${totalRow}条`, showSizeChanger: true, showQuickJumper: true, pageSize: state.pageSize, current: state.pageNumber, total: state.total, pageSizeOptions: ['10', '20', '50', '100'], hideOnSinglePage: true, }, loading: state.loading, onChange: handleTableChange, }, listProps, search: (params?: SearchOption) => search({ ...params, pageNumber: 1 }), refresh: search, } } export default usePageTable