原文链接

    1. import React, { useEffect, useReducer, useCallback } from 'react'
    2. import { Table } from 'antd';
    3. import { ArgTableProps, paginationInitialType, initialStateType, actionType } from './type'
    4. const useAsyncTable: React.FC<ArgTableProps> = props => {
    5. const { owncolumns, queryAction, params, baseProps } = props
    6. // 分页数据
    7. const paginationInitial: paginationInitialType = {
    8. current: 1,
    9. pageSize: 10,
    10. total: 0,
    11. }
    12. // table组件全量数据
    13. const initialState: initialStateType = {
    14. loading: false,
    15. pagination: paginationInitial,
    16. dataSource: []
    17. }
    18. const reducer = (state: initialStateType, action: actionType) => {
    19. const { payload } = action
    20. switch (action.type) {
    21. case 'TOGGLE_LOADING':
    22. return { ...state, loading: !state.loading }
    23. case 'SET_PAGINATION':
    24. return { ...state, pagination: payload.pagination }
    25. case 'SET_DATA_SOURCE':
    26. return { ...state, dataSource: payload.dataSource }
    27. default:
    28. return state
    29. }
    30. }
    31. const [state, dispatch] = useReducer(reducer, initialState)
    32. // 改变页码
    33. function handleTableChange(payload: any) {
    34. if (payload) {
    35. const { current } = payload
    36. dispatch({
    37. type: 'SET_PAGINATION',
    38. payload: {
    39. pagination: {
    40. ...state.pagination,
    41. current
    42. }
    43. }
    44. })
    45. }
    46. }
    47. // useCallback包装请求,缓存依赖,优化组件性能
    48. const fetchDataWarp = useCallback(
    49. fetchData,
    50. [params, state.pagination.current, owncolumns, queryAction],
    51. )
    52. async function fetchData() {
    53. dispatch({
    54. type: 'TOGGLE_LOADING'
    55. })
    56. // 分页字段名称转换
    57. const { current: indexfrom, pageSize: counts } = state.pagination
    58. let res = await queryAction({ indexfrom, counts, ...params }).catch(err => {
    59. dispatch({ type: 'TOGGLE_LOADING' })
    60. return {}
    61. })
    62. // 关闭loading
    63. dispatch({
    64. type: 'TOGGLE_LOADING'
    65. })
    66. if (res.result === 200) {
    67. const { totalcounts, list } = res
    68. dispatch({
    69. type: 'SET_PAGINATION',
    70. payload: {
    71. pagination: { ...state.pagination, total: totalcounts }
    72. }
    73. })
    74. // 回填list数据
    75. dispatch({
    76. type: 'SET_DATA_SOURCE',
    77. payload: {
    78. dataSource: list
    79. }
    80. })
    81. }
    82. }
    83. useEffect(() => {
    84. fetchDataWarp()
    85. }, [fetchDataWarp])
    86. return (
    87. <Table
    88. columns={owncolumns(fetchData)}
    89. pagination={state.pagination}
    90. dataSource={state.dataSource}
    91. loading={state.loading}
    92. onChange={handleTableChange}
    93. {...baseProps}
    94. />
    95. )
    96. }
    97. export default useAsyncTable
    属性 类型 默认值 备注
    owncolumns (updatefunc:Function): columns 必选参数 updatefunc用于刷新列表
    queryAction (payload): Promise 必选参数 用于列表数据获取
    baseProps TableProps from antd 任选 antd的基础props
    params object {} 请求附加参数
    1. const getColumn: getColumnType = updateMethod => {
    2. return [
    3. {
    4. title: "项目名称",
    5. dataIndex: "project_name",
    6. key: "project_name",
    7. },
    8. {
    9. title: '操作',
    10. key: 'setting',
    11. width: 200,
    12. render: (text: any, record: any, index: number) => {
    13. return (
    14. <div>
    15. <Button type="primary" style={{ marginRight: '5px' }}>查看</Button>
    16. <Popconfirm
    17. title="此操作将永久删除该项目, 是否继续?"
    18. okText="确定"
    19. cancelText="取消"
    20. onConfirm={() => {
    21. updateMethod()
    22. }}
    23. >
    24. <Button type="danger">删除</Button>
    25. </Popconfirm>
    26. </div>
    27. )
    28. }
    29. }
    30. ];
    31. }
    32. render(){
    33. return (
    34. <ArgTable
    35. owncolumns={updatefunc => getColumn(updatefunc)}
    36. queryAction={API.http_getProjectList}
    37. baseProps={{ rowKey: record => record.project_id }}
    38. params={searchData}
    39. />
    40. )
    41. }