尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Refine + TanStack Table 分页实战:基于 @refinedev/react-table 的 useTable 分页实现与原理
Refine TanStack Table 分页实战基于 refinedev/react-table 的 useTable 分页实现与原理【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine本指南以 Refine 官方文档中useTable分页章节的可运行示例_partial-pagination-live-preview.md为骨架完整讲解如何用refinedev/react-table在 Refine v5 项目中实现服务端/客户端分页表格从安装、完整可复制的分页 UI 代码到setPageIndex、setPageSize、getPrePaginationRowModel等 TanStack Table API 的逐一拆解并结合refinedev/react-table的源码packages/react-table/src/useTable/index.ts与测试用例packages/react-table/src/useTable/index.spec.ts讲清底层工作原理。读完你可以独立搭建一个带页码跳转、上一页/下一页、每页条数切换的 headless 分页表格。背景headless 的 TanStack Table 适配器Refine 官方为 TanStack Table 中明确说明所有 TanStack Table 的特性都被支持官方示例可以直接复制粘贴到项目中使用。useTable是从refinedev/core包中的useTable扩展而来底层通过useList获取数据。也就是说你既能使用 coreuseTable的全部能力资源解析、数据提供器对接、syncWithLocation、实时更新等也能使用 TanStack Table 的全部表格能力。安装使用你习惯的包管理器安装适配包npm install refinedev/react-table # 或 pnpm add refinedev/react-table # 或 yarn add refinedev/react-table该包内部依赖tanstack/react-tableRefine 会将其作为依赖一并安装无需手动安装 TanStack Table 本身。完整示例一个带分页控制的帖子列表下面这段代码完整来自官方分页示例见 documentation/docs/packages/tanstack-table/examples/_partial-pagination-live-preview.md。它渲染一个posts资源列表并在表格下方构建了一个完全自绘的分页条首页/上一页/下一页/末页四个按钮、当前页码与总页数、跳页输入框、每页条数下拉选择以及总行数统计。import React from react; import { useTable } from refinedev/react-table; import { ColumnDef, flexRender } from tanstack/react-table; interface IPost { id: number; title: string; content: string; status: published | draft | rejected; } const PostList: React.FC () { const columns React.useMemoColumnDefIPost[]( () [ { id: id, header: ID, accessorKey: id, }, { id: title, header: Title, accessorKey: title, }, { id: status, header: Status, accessorKey: status, }, { id: createdAt, header: CreatedAt, accessorKey: createdAt, }, ], [], ); const { reactTable: { getHeaderGroups, getRowModel, // 分页相关 API getState, setPageIndex, getCanPreviousPage, getPageCount, getCanNextPage, nextPage, previousPage, setPageSize, getPrePaginationRowModel, }, } useTable({ columns, }); return ( div table thead {getHeaderGroups().map((headerGroup) ( tr key{headerGroup.id} {headerGroup.headers.map((header) { return ( th key{header.id} {header.isPlaceholder ? null : ( {flexRender( header.column.columnDef.header, header.getContext(), )} / )} /th ); })} /tr ))} /thead tbody {getRowModel().rows.map((row) { return ( tr key{row.id} {row.getVisibleCells().map((cell) { return ( td key{cell.id} {flexRender( cell.column.columnDef.cell, cell.getContext(), )} /td ); })} /tr ); })} /tbody /table {/* 分页 UI 可以任意自绘这里只是最基础的实现 */} div button onClick{() setPageIndex(0)} disabled{!getCanPreviousPage()} {} /button button onClick{() previousPage()} disabled{!getCanPreviousPage()} {} /button button onClick{() nextPage()} disabled{!getCanNextPage()} {} /button button onClick{() setPageIndex(getPageCount() - 1)} disabled{!getCanNextPage()} {} /button span divPage/div strong {getState().pagination.pageIndex 1} of {getPageCount()} /strong /span span | Go to page: input typenumber defaultValue{getState().pagination.pageIndex 1} onChange{(e) { const page e.target.value ? Number(e.target.value) - 1 : 0; setPageIndex(page); }} / /span select value{getState().pagination.pageSize} onChange{(e) { setPageSize(Number(e.target.value)); }} {[10, 20, 30, 40, 50].map((pageSize) ( option key{pageSize} value{pageSize} Show {pageSize} /option ))} /select /div div{getPrePaginationRowModel().rows.length} Rows/div /div ); };把PostList挂到路由上并确保Refine中注册了posts资源与对应数据提供器即可运行。分页 API 逐一拆解示例中从useTable()返回的reactTable对象里解构出来的 9 个分页相关 API都是 TanStack Table v8 的标准接口API作用示例中的用法getState()读取当前表格状态含pagination.pageIndex、pagination.pageSizegetState().pagination.pageIndex 1显示当前页TanStack 的pageIndex从 0 开始显示时 1setPageIndex(index)跳转到指定页0 基索引首页按钮setPageIndex(0)末页按钮setPageIndex(getPageCount() - 1)跳页输入框把用户输入的 1 基页码减 1 后传入getCanPreviousPage()是否存在上一页即是否在第一页作为、按钮的disabled条件getPageCount()总页数末页按钮与Page x of y展示getCanNextPage()是否存在下一页即是否在末页作为、按钮的disabled条件nextPage()下一页按钮点击事件previousPage()上一页按钮点击事件setPageSize(size)设置每页条数select的onChange取值来自[10, 20, 30, 40, 50]getPrePaginationRowModel()返回分页前的行模型全量行getPrePaginationRowModel().rows.length展示总行数两点关键提示pageIndex是 0 基、currentPage是 1 基TanStack Table 内部pageIndex从 0 开始计数因此显示页码要1跳页输入框要把用户输入减 1。跳页输入的边界处理const page e.target.value ? Number(e.target.value) - 1 : 0;—— 输入为空时回退到第 0 页第一页避免NaN传入。底层原理useTable 是如何把分页与 Refine 数据请求联动起来的官方分页章节文档指出「setPageSize等方法的每次变更都会触发一次新的数据提供器请求」。要理解这一点需要看 packages/react-table/src/useTable/index.ts 的实现const isPaginationEnabled refineCoreProps.pagination?.mode ! off; // ... const reactTableResult useReactTableTData({ data: data?.data ?? [], // ... initialState: { pagination: { pageIndex: currentPage - 1, pageSize: pageSizeCore, }, // ... }, pageCount, manualPagination: true, // ... });关键机制有三条manualPagination: true手动分页TanStack Table 不再在客户端自动切片data而是把分页状态完全交给开发者/外层框架控制配合 Refine 的服务端数据获取。初始状态双向映射coreuseTable的currentPage1 基映射为 TanStack 的pageIndex0 基即currentPage - 1pageSize直接透传。同时把 core 返回的pageCount作为 TanStack 的总页数来源。状态同步useEffect 反向联动当用户在 UI 上调用setPageIndex/setPageSize改变 TanStack 状态后两个useEffect会把新的pageIndex 1与pageSize写回 core 的setCurrentPage/setPageSizeCore从而触发useList重新请求数据useEffect(() { if (pageIndex ! undefined) { setCurrentPage(pageIndex 1); } }, [pageIndex]); useEffect(() { if (pageSize ! undefined) { setPageSizeCore(pageSize); } }, [pageSize]);测试用例印证了这一行为packages/react-table/src/useTable/index.spec.ts默认无参数时state.pagination?.pageIndex为0、pageSize为10、pageCount为1传入pagination: { currentPage: 2, pageSize: 1 }后core 侧currentPage为2、pageSize为1TanStack 侧pageIndex为1、pageSize为1pageCount变为3。配置项pagination.currentPage / pageSize / mode分页行为通过useTable的refineCoreProps.pagination配置完整参数表见 useTable 官方文档useTable({ refineCoreProps: { pagination: { currentPage: 2, // 初始页码1 基默认 1 pageSize: 10, // 初始每页条数默认 10 mode: server, // server | client | off默认 server }, }, });参数类型默认值说明pagination.currentPagenumber1初始页码1 基pagination.pageSizenumber10初始每页条数pagination.modeoff \| server \| clientserver分页模式见下三种mode的含义server默认服务端分页。数据提供器根据currentPage与pageSize请求对应页的数据TanStack Table 通过manualPagination: true不做客户端切片。这也是示例中getPrePaginationRowModel().rows.length能拿到总数的原因——总行数来自服务端返回的total。client客户端分页。一次性拉取全量记录由 TanStack Table 在客户端完成切片。适用于数据量较小的场景。off关闭分页一次请求拉取全部记录。从源码看mode: off时isPaginationEnabled为false同时排序sorting.length 0或筛选crudFilters.length 0变化后只有分页启用时才会把页码重置回第 1 页if (sorting.length 0 isPaginationEnabled !isFirstRender) { setCurrentPage(1); }与排序、筛选的联动换页重置除了分页本身源码中还有两处值得注意的联动逻辑packages/react-table/src/useTable/index.ts 第 135-176 行排序变化sorting变更时将 TanStack 的排序状态转换回 Refine 的CrudSortingdesc↔desc其余为asc并通过setSorters写回 core触发重新请求列筛选变化columnFilters变更时通过工具函数columnFiltersToCrudFilters/crudFiltersToColumnFilters与 core 的 filters 状态双向同步并补回被移除的筛选器getRemovedFilters。二者的共同点是在分页启用且非首次渲染时把页码重置回第 1 页避免用户停留在第 5 页时排序/筛选导致越界。测试用例同样覆盖了这些行为index.spec.ts中针对sorters.mode、filters.mode的it.each用例验证manualSorting/manualFiltering与服务端模式的对应关系。URL 状态同步syncWithLocation如果希望分页状态以及其他表格状态同步到 URL 查询参数从而支持收藏、分享链接可以启用syncWithLocationuseTable({ refineCoreProps: { syncWithLocation: true, }, });启用后pageIndex、pageSize等状态会自动编码进 URL queryURL 变化时表格状态也会随之恢复。默认它会读取Refine组件上的syncWithLocation全局配置。进阶客户端分页与关闭分页按数据规模选择模式// 客户端分页全量拉取、本地切片 useTable({ refineCoreProps: { pagination: { mode: client, }, }, }); // 关闭分页一次拉取全部记录 useTable({ refineCoreProps: { pagination: { mode: off, }, }, });注意客户端分页模式下TanStack Table 的getFilteredRowModel、getSortedRowModel等客户端行模型仍然可用源码中仅在对应服务端模式开启时才置为undefined因此客户端分页可以方便地与客户端排序/筛选组合使用。参考示例仓库内完整的可运行示例见 examples/table-react-table-basic它与本指南的分页示例同源对应文档页面的 CodeSandbox 链接。相关文档还包括useTable Hook 完整参考属性 / 返回值 / FAQTanStack Table 集成介绍Tables 指南guides-conceptscore useTable 数据 Hook 文档适配器源码 与 测试用例【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

CookLikeHOC 复刻指南:砂锅肉汁素鸡的批量预制与单份出品全流程

CookLikeHOC 复刻指南:砂锅肉汁素鸡的批量预制与单份出品全流程

CookLikeHOC 复刻指南:砂锅肉汁素鸡的批量预制与单份出品全流程 【免费下载链接】CookLikeHOC 🥢像老乡鸡🐔那样做饭。已添加2026年发布的《老乡鸡菜品溯源报告 2.0中新出现的菜品。主要部分于2024年完工,非老乡鸡官方仓库。文字来…

📅 2026/9/12 21:38:39
氢储能在微电网中的优化调度与Matlab实现

氢储能在微电网中的优化调度与Matlab实现

1. 项目概述:氢储能与微电网的跨界融合在能源转型的大背景下,微电网作为分布式能源的重要载体,正面临如何高效消纳可再生能源的挑战。传统锂电池储能在长时间储能场景中存在能量密度低、循环寿命短等瓶颈,而氢储能凭借其高能量密度…

📅 2026/9/12 21:38:39
Turso 差分模糊测试器(Differential Fuzzer)实战指南:以 SQLite 为 Oracle 捕获正确性缺陷

Turso 差分模糊测试器(Differential Fuzzer)实战指南:以 SQLite 为 Oracle 捕获正确性缺陷

Turso 差分模糊测试器(Differential Fuzzer)实战指南:以 SQLite 为 Oracle 捕获正确性缺陷 【免费下载链接】turso A SQL database in Rust: SQLite-compatible, now also speaking Postgres (experimental). The LLVM of databases. 项目地…

📅 2026/9/12 21:33:39
MORE NEWS

更多资讯

📰

从629张小数据集到可部署模型:基于YOLOv8的停车位检测实战指南

简介:面向YOLO系列目标检测学习者的停车位检测数据集,包含629张带标注的实景图像,覆盖不同角度与场景下的车位区域,适合用于车位检测、智能停车等视觉任务的模型训练与效果验证。包内已按训练/验证需求完成数据集划分,…

📰

STM32智能小车核心板:从原理图到PCB布局与固件调试全攻略

简介:面向STM32F103C8T6智能小车开发者的一份核心板硬件工程设计资源。整套图纸用Altium Designer绘制,覆盖原理图、PCB图与元件库,不仅适用于智能小车,也可移植到其他STM32F103C8T6核心板场景,适合嵌入式入门者学习画…

📰

基于Java与MooseFS的分布式文件系统:核心原理与工程实践

简介:这是基于Java与Moosefs的分布式文件系统完整项目资料,面向高校学生与Java开发人员,可用于课程设计、毕业设计及分布式存储技术实战学习。压缩包共200个文件,以jar依赖库、java源码、class编译产物、html页面为主体&#xff0…

📰

YOLOv5+CRNN车牌识别实战:从检测、训练到TensorRT部署

简介:基于YOLOv5与CRNN的中文车牌识别系统,是一份面向计算机相关专业毕业设计、课程设计的高分项目源码包,适合软件工程、人工智能、自动化等方向学生及入门进阶学习者参考。资源已通过导师认可、答辩评审95分,代码全部测试运行成…

📰

PHP卡密验证系统设计:数据表、生成算法与后台管理实战

简介:这是一套基于PHP开发的卡密验证系统,面向需要为在线服务、游戏或软件产品搭建激活码/兑换码验证机制的个人开发者与中小企业。系统提供完整的前端交互与后台管理,覆盖卡密生成与状态管理、订单及支付回调处理、用户权限管理、销售统计等…

📰

Roo Code 连接 LLM Provider 完全指南:从 API Key 到首个 AI Agent 任务

Roo Code 连接 LLM Provider 完全指南:从 API Key 到首个 AI Agent 任务 【免费下载链接】Roo-Code Roo Code gives you a whole dev team of AI agents in your code editor. 项目地址: https://gitcode.com/GitHub_Trending/ro/Roo-Code Roo Code 是一个运…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬