🌲系列一:跟着官方示例学习 @tanStack-table --- Basic
🌲系列二:跟着官方示例学习 @tanStack-table --- Header Groups
🌲系列三:跟着官方示例学习 @tanStack-table --- Column Filters
🌲系列四:跟着官方示例学习 @tanStack-table --- Column Ordering
🌲系列五:跟着官方示例学习 @tanStack-table --- Sticky Column Pinning
🌲系列六:跟着官方示例学习 @tanStack-table --- Column Sizing
🌲系列七:跟着官方示例学习 @tanStack-table --- Expanding
今天我们来聊聊一个经典而又不可忽视的功能:分页(Pagination
)!没错,当你的数据量一多起来,分页就是你的好朋友,能帮你分门别类、有条不紊地展示数据。
🌬️ 前端分页
🛠 基础准备:Pagination 的状态管理
TanStack Table
没有强制你用它内置的分页逻辑,但如果你想用起来也非常方便。我们一般用 React
的 useState
来管理分页状态,比如这样:
tsx
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
-
pageIndex
: 当前页(从 0 开始) -
pageSize
: 每页多少条数据
然后把它传给 useReactTable
的 state.pagination
和 onPaginationChange
👇
tsx
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(), // 🚨 别忘了这个
state: {
pagination,
},
onPaginationChange: setPagination,
})
📌 getPaginationRowModel() 是分页的关键插件,没有它分页就不工作哟~
📋 表格渲染 & 分页操作面板
我们再来看看分页操作的 UI 控制,像这样:
tsx
<button onClick={() => table.firstPage()} disabled={!table.getCanPreviousPage()}>
{'<<'}
</button>
<button onClick={() => table.previousPage()} disabled={!table.getCanPreviousPage()}>
{'<'}
</button>
<button onClick={() => table.nextPage()} disabled={!table.getCanNextPage()}>
{'>'}
</button>
<button onClick={() => table.lastPage()} disabled={!table.getCanNextPage()}>
{'>>'}
</button>
是不是很直观?TanStack Table
提供了这些非常人性化的方法:
-
table.firstPage()
→ 跳转到第一页 -
table.previousPage()
→ 上一页 -
table.nextPage()
→ 下一页 -
table.lastPage()
→ 跳转到最后一页 -
table.getCanPreviousPage()
/table.getCanNextPage()
→ 判断是否还能翻页
而我们也可以加一个 跳页输入框 和 页大小切换器,让交互更灵活:
tsx
<input
type="number"
onChange={e => table.setPageIndex(Number(e.target.value) - 1)}
defaultValue={table.getState().pagination.pageIndex + 1}
/>
<select
value={table.getState().pagination.pageSize}
onChange={e => table.setPageSize(Number(e.target.value))}
/>
🔗 Pagination API
🤔 分页和服务端结合?
一般来说,在一个实际项目中,数据是从服务器拉取的,那分页的逻辑可不能全靠前端来搞定了。此时就轮到我们的"服务端分页"大显身手啦!
我们需要做两件事:
1️⃣ 使用 manualPagination: true 通知表格:分页由我接管
tsx
manualPagination: true,
这个配置告诉 TanStack Table
:"嘿,我要自己处理分页逻辑啦,别给我管页数和数据啦!"💪
同时注意:既然分页逻辑是手动的,就不需要使用 getPaginationRowModel()
了。
2️⃣ 使用 @tanstack/react-query 拉数据,监听分页变化自动刷新
我们使用 useQuery
来获取数据,并把 pagination
状态作为 queryKey
的一部分。
tsx
const dataQuery = useQuery({
queryKey: ['data', pagination],
queryFn: () => fetchData(pagination), // 👈 你根据分页参数请求数据
placeholderData: keepPreviousData, // 🤩 保持上次的数据,避免翻页时空白闪屏
})
是不是很丝滑?还可以用 isFetching
显示加载动画,用户体验 +1!
tsx
{dataQuery.isFetching ? 'Loading...' : null}
3️⃣ 配置表格的核心参数
表格的 data
直接来自 dataQuery.data?.rows
,并且还要告诉它:总共有多少行数据(rowCount
):
tsx
const table = useReactTable({
data: dataQuery.data?.rows ?? [],
columns,
rowCount: dataQuery.data?.rowCount, // 👈 告诉表格总共有多少行
state: {
pagination,
},
onPaginationChange: setPagination,
manualPagination: true,
getCoreRowModel: getCoreRowModel(),
})
🔥 小贴士:从
v8.13.0
开始,你也可以用rowCount
来自动计算pageCount
,不再非得手动传pageCount
,是不是方便很多!