浏览文档目录
第 18 课 · 无头表格

把 Issue 数据组织成无头表格

用类型化列定义、核心行模型和 flexRender 连接数据与语义化 table 标记,同时保留完整的样式控制权。

TanStack Table入门24 分钟REV 01Markdown .md
完成后你将能够

能构建类型安全、行标识稳定且不依赖预制 UI 的基础数据表。

01

Table 管逻辑,不替你设计界面

TanStack Table 是无头库:它产生列、表头、行、单元格和交互状态模型,但最终 HTML、组件、键盘行为和 CSS 仍由应用负责。先用原生 table 建立正确语义,再把同一实例接入你的设计系统;不要寻找一个不存在的 Table 组件。

02

列定义同时描述数据与渲染

createColumnHelper 把列约束到 Issue 类型。accessor 列应返回可排序、筛选或分组的原始值;只负责按钮或链接的 display 列不应伪造 accessor。函数 accessor 必须提供稳定 id 或字符串 header。

src/features/issues/IssueTable.tsxtsx
import {
  createColumnHelper, flexRender, getCoreRowModel, useReactTable,
} from '@tanstack/react-table'

type Issue = { id: string; title: string; status: 'open' | 'closed' }
const column = createColumnHelper<Issue>()
const columns = [
  column.accessor('title', { header: 'Title' }),
  column.accessor('status', { header: 'Status' }),
  column.display({ id: 'actions', cell: ({ row }) => <a href={`/issues/${row.original.id}`}>View</a> }),
]

export function IssueTable({ issues }: { issues: Issue[] }) {
  const table = useReactTable({
    data: issues, columns, getRowId: (issue) => issue.id,
    getCoreRowModel: getCoreRowModel(),
  })
  return <table><thead>{table.getHeaderGroups().map((group) => (
    <tr key={group.id}>{group.headers.map((header) => <th key={header.id}>
      {header.isPlaceholder ? null : 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>
}
03

行模型是一条显式处理管线

getCoreRowModel 把原始 data 转成基础行。之后只有在需要排序、筛选或分页时才加入对应行模型。用 getRowId 返回业务 id,避免列表重排后选择状态、展开状态或编辑状态跟着数组位置漂移。空数据应传稳定空数组并渲染明确空状态。

实践

把本课变成可验证的能力

完成检查点

能从同一份 Issue 类型推导列值、行对象和渲染上下文,并说明 Table 为什么不输出固定组件。

动手练习

为 Issue 列表增加 title、status 和 priority 三列,再添加一个没有 accessor 的“查看详情”展示列。

验证方法

交换数据顺序后 row.id 仍应等于 Issue id;空数组应正常渲染表头和空状态,类型检查拒绝不存在的 accessor key。

常见错误
  • 把 accessor 返回对象,随后期待默认排序可以理解业务字段。
  • 使用数组索引作为服务端数据的稳定行标识。
SOURCE REFERENCES · CHECKED 2026-08-03https://tanstack.com/table/latest/docs/introductionhttps://tanstack.com/table/latest/docs/guide/column-defshttps://tanstack.com/table/latest/docs/guide/rows