关于 tanstack-table
TanStack Table 是面向数据密集型界面的模块化 React 表格库。本技能介绍安装方式,以及类型化列定义、行模型和受控表格状态的用法。
主要功能
- 01模块化行模型流程
- 02类型安全的列定义
- 03排序与筛选模式
- 04分页和选择状态
- 05列可见性与尺寸指导
适用场景
- 01构建可排序的数据表
- 02添加列筛选与全局筛选
- 03控制分页和行选择
- 04动态显示或调整列宽
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ marcioaltoe/ skills --skill tanstack-table安装后在 Claude Code 中输入/tanstack-table确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlrules/col-column-defs.mdexp-expanding.mdfilt-column-filtering.mdfilt-global-filtering.mdpag-pagination.mdrm-row-models.mdsel-row-selection.mdsize-column-sizing.mdsort-sorting.mdtable-setup.mdvis-column-visibility.md详细介绍
TanStack Table
版本:@tanstack/react-table@latest 要求:React 16.8+,建议使用 TypeScript
快速设置
npm install @tanstack/react-table
import {
useReactTable,
getCoreRowModel,
flexRender,
createColumnHelper,
} from '@tanstack/react-table'
type User = {
name: string
age: number
status: string
}
const columnHelper = createColumnHelper<User>()
const columns = [
columnHelper.accessor('name', { header: 'Name' }),
columnHelper.accessor('age', { header: 'Age' }),
columnHelper.accessor('status', { header: 'Status' }),
columnHelper.display({
id: 'actions',
cell: (props) => <button onClick={() => edit(props.row.original)}>Edit</button>,
}),
]
function App() {
const [data] = useState<User[]>([]) // must be stable reference
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
})
return (
<table>
<thead>
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th key={header.id}>
{flexRender(header.column.columnDef.header, header.getContext())}
</th>
))}
</tr>
))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => (
<td key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
)
}
行模型(仅导入所需内容)
TanStack Table 采用模块化设计。仅导入实际使用的行模型:
import {
getCoreRowModel, // required
getSortedRowModel, // client-side sorting
getFilteredRowModel, // client-side filtering
getPaginationRowModel,// client-side pagination
getExpandedRowModel, // expanding/sub-rows
getGroupedRowModel, // grouping + aggregation
getFacetedRowModel, // faceted values
getFacetedUniqueValues,
getFacetedMinMaxValues,
} from '@tanstack/react-table'
处理管道顺序:Core -> Filtered -> Grouped -> Sorted -> Expanded -> Paginated -> Rendered
规则类别
| 优先级 | 类别 | 规则文件 | 影响 |
|---|---|---|---|
| CRITICAL | 表格设置 | rules/table-setup.md | 正确创建表格,保持数据引用稳定 |
| CRITICAL | 列定义 | rules/col-column-defs.md | 数据模型、渲染、类型安全 |
| CRITICAL | 行模型 | rules/rm-row-models.md | 模块化导入,处理管道顺序 |
| HIGH | 排序 | rules/sort-sorting.md | 客户端/服务端排序,自定义排序函数 |
| HIGH | 列筛选 | rules/filt-column-filtering.md | 按列筛选,自定义筛选函数 |
| HIGH | 全局筛选 | rules/filt-global-filtering.md | 全表搜索,全局筛选函数 |
| HIGH | 分页 | rules/pag-pagination.md | 客户端/服务端分页,页面状态 |
| MEDIUM | 行选择 | rules/sel-row-selection.md | 复选框/单选框选择,选择状态 |
| MEDIUM | 列可见性 | rules/vis-column-visibility.md | 动态显示/隐藏列 |
| MEDIUM | 列宽调整 | rules/size-column-sizing.md | 列宽、调整大小、性能 |
| LOW | 展开 | rules/exp-expanding.md | 子行、详情面板、层级数据 |
关键规则
始终遵循
- 保持
data引用稳定——使用useState、useMemo,或在组件外定义,以避免无限重新渲染 - 使用
createColumnHelper<TData>()——确保列定义具有最高的类型安全性 - 仅导入所需的行模型——如果不进行客户端排序,就不要导入
getSortedRowModel - 使用
flexRender——渲染列定义中的表头/单元格/页脚模板 - 使用
getVisibleCells()——不要使用getAllCells(),以遵循列可见性设置 - 使用
getRowModel()——获取应用所有功能(筛选、排序、分页)后的最终行模型 - 使用
state+on*Change控制状态——用于排序、筛选、分页、选择等
绝不这样做
- 内联定义
data——useReactTable({ data: fetchData() })会导致无限重新渲染 - 在渲染期间定义
columns——列数组必须保持稳定(在组件外定义或使用useMemo) - 使用
getAllCells()进行渲染——它会忽略列可见性;应使用getVisibleCells() - 对同一功能混用
initialState和state——state会覆盖initialState - 将客户端行模型与
manual*选项混用——如果manualSorting: true,就不要导入getSortedRowModel - 忘记
getRowId——如果不设置,行 ID 默认使用索引,重新获取数据后会导致选择状态错乱
关键模式
// Controlled sorting state
const [sorting, setSorting] = useState<SortingState>([])
const table = useReactTable({
data, columns,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
state: { sorting },
onSortingChange: setSorting,
})
// Header click handler
<th onClick={header.column.getToggleSortingHandler()}>
{flexRender(header.column.columnDef.header, header.getContext())}
{{ asc: ' 🔼', desc: ' 🔽' }[header.column.getIsSorted() as string] ?? ''}
</th>
// Server-side pagination
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 })
const table = useReactTable({
data, columns,
getCoreRowModel: getCoreRowModel(),
manualPagination: true,
rowCount: serverData.totalRows,
state: { pagination },
onPaginationChange: setPagination,
})
// Row selection with checkbox column
columnHelper.display({
id: 'select',
header: ({ table }) => (
<input type="checkbox" checked={table.getIsAllRowsSelected()}
onChange={table.getToggleAllRowsSelectedHandler()} />
),
cell: ({ row }) => (
<input type="checkbox" checked={row.getIsSelected()}
disabled={!row.getCanSelect()}
onChange={row.getToggleSelectedHandler()} />
),
})
// Column filtering
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
const table = useReactTable({
data, columns,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
state: { columnFilters },
onColumnFiltersChange: setColumnFilters,
})
// Filter input
<input value={column.getFilterValue() ?? ''} onChange={e => column.setFilterValue(e.target.value)} />
// Stable row IDs for selection across re-fetches
const table = useReactTable({
data, columns,
getRowId: (row) => row.uuid,
getCoreRowModel: getCoreRowModel(),
})
评论
支持 Markdown