You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React JS中如何在antd Table组件内使用自定义分页功能

实现思路

  1. 关闭antd Table内置分页:将pagination属性设为false,无需修改原有筛选、排序逻辑,Table的onChange事件仍会正常返回筛选、排序参数
  2. 独立维护分页状态:单独引入antd Pagination组件放在Table外部,自主控制分页逻辑、上下页按钮状态
  3. 批量拉取+前端分页:每次拉取50条数据追加到本地缓存,前端按每页10条切片渲染,根据本地已拉取数据量和后台总数据量判断是否还有未拉取数据,控制下一页按钮启用状态

完整示例代码

import { useState, useEffect } from 'react'
import { Table, Pagination } from 'antd'

// 模拟接口请求,实际替换为你的业务接口即可
const mockApi = (offset, limit) => {
  return new Promise(resolve => {
    setTimeout(() => {
      const total = 100 // 后台总数据量,实际由接口返回
      const list = Array.from({ length: limit }, (_, i) => ({
        id: offset + i + 1,
        name: `数据${offset + i + 1}`
      })).filter(item => item.id <= total)
      resolve({ data: { list, total } })
    }, 500)
  })
}

const CustomPaginationTable = () => {
  const [allFetchedData, setAllFetchedData] = useState([]) // 本地已拉取的全量数据
  const [currentPage, setCurrentPage] = useState(1)
  const pageSize = 10 // 每页展示10条
  const [totalBackend, setTotalBackend] = useState(0) // 后台总数据量
  const [loading, setLoading] = useState(false)

  // 计算已拉取数据可支持的最大页数
  const maxFetchedPage = Math.ceil(allFetchedData.length / pageSize)
  // 计算后台总数据对应的总页数
  const totalPage = Math.ceil(totalBackend / pageSize)
  // 是否还有未拉取的后台数据
  const hasMore = allFetchedData.length < totalBackend
  // 当前页要展示的10条数据
  const currentPageData = allFetchedData.slice((currentPage - 1) * pageSize, currentPage * pageSize)

  // 拉取数据逻辑,每次拉取50条
  const fetchBatchData = async () => {
    setLoading(true)
    const res = await mockApi(allFetchedData.length, 50)
    setAllFetchedData(prev => [...prev, ...res.data.list])
    setTotalBackend(res.data.total)
    setLoading(false)
  }

  // 首次加载拉取第一批数据
  useEffect(() => {
    fetchBatchData()
  }, [])

  // 分页切换逻辑
  const handlePageChange = (page) => {
    // 要跳转的页数超过已拉取数据支持的最大页数,且还有未拉取数据时,触发新的拉取
    if (page > maxFetchedPage && hasMore) {
      fetchBatchData().then(() => {
        setCurrentPage(page)
      })
      return
    }
    setCurrentPage(page)
  }

  // 自定义分页项渲染,控制上下页按钮禁用状态
  const paginationItemRender = (page, type, originalElement) => {
    if (type === 'next') {
      // 下一页禁用条件:已经到最后一页 或 没有更多未拉取数据且已经到已拉取数据的最后一页
      const isNextDisabled = currentPage >= totalPage || (currentPage >= maxFetchedPage && !hasMore)
      return { ...originalElement, props: { ...originalElement.props, disabled: isNextDisabled } }
    }
    if (type === 'prev') {
      const isPrevDisabled = currentPage <= 1
      return { ...originalElement, props: { ...originalElement.props, disabled: isPrevDisabled } }
    }
    return originalElement
  }

  // 表格列配置,可根据实际需求修改
  const columns = [
    { title: 'ID', dataIndex: 'id', key: 'id', sorter: (a,b) => a.id - b.id },
    { title: '名称', dataIndex: 'name', key: 'name' }
  ]

  return (
    <div>
      <Table
        columns={columns}
        dataSource={currentPageData}
        loading={loading}
        pagination={false} // 关闭内置分页
        onChange={(pagination, filters, sorter) => {
          // 原有筛选、排序逻辑直接在这里处理即可,无需修改
          console.log('筛选参数:', filters, '排序参数:', sorter)
        }}
      />
      <div style={{ marginTop: 16, textAlign: 'right' }}>
        <Pagination
          current={currentPage}
          pageSize={pageSize}
          total={totalBackend}
          onChange={handlePageChange}
          itemRender={paginationItemRender}
          showTotal={total => `共 ${total} 条数据`}
        />
      </div>
    </div>
  )
}

export default CustomPaginationTable

关键说明

  • 关闭内置分页后不会影响原有筛选、排序功能:Table的onChange事件仍会正常返回filters(筛选参数)、sorter(排序参数),原有处理逻辑可以直接复用
  • 上下页按钮控制:通过Pagination的itemRender属性自定义按钮渲染,可自由控制禁用状态,不需要额外自定义整个分页组件,样式和antd原生保持一致
  • 批量拉取逻辑:每次拉取50条追加到本地缓存,只有当用户翻到已拉取数据的最后一页且还有未拉取数据时,才会触发下一批数据拉取,符合需求中的next按钮交互逻辑
  • 如果你需要完全自定义分页组件的UI,也可以不用antd的Pagination,自己写上下页按钮和页码展示,逻辑和上述示例完全一致

内容的提问来源于stack exchange,提问作者Mei Lie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 22:54:00