跟着官方示例学习 @tanStack-table --- Basic

🥥 前沿

作为一名前端,可能对"表格"这个 UI 组件并不陌生,市面上大多数组件库也都会提供表格组件,但说到 @tanstack/react-table 这个库时,脑海里可能冒出三连问:

🌚 它是谁? 🧠 我该怎么开始用?

别急!今天我们就通过官方示例代码来拆解一下 @tanstack/react-table 的基本用法!

🔔 对官方示例代码可能存在一些删减的情况

代码地址🔗:tanstack.com/table/lates...

tsx 复制代码
type Person = {
  firstName: string;
  lastName: string;
  age: number;
  visits: number;
  status: string;
  progress: number;
};

const defaultData: Person[] = [
  {
    firstName: 'tanner',
    lastName: 'linsley',
    age: 24,
    visits: 100,
    status: 'In Relationship',
    progress: 50,
  },
  {
    firstName: 'tandy',
    lastName: 'miller',
    age: 40,
    visits: 40,
    status: 'Single',
    progress: 80,
  },
  {
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  },
];

const columnHelper = createColumnHelper<Person>();

const columns = [
  columnHelper.accessor('firstName', {
    cell: (info) => info.getValue(),
    footer: (info) => info.column.id,
  }),
  columnHelper.accessor((row) => row.lastName, {
    id: 'lastName',
    cell: (info) => <i>{info.getValue()}</i>,
    header: () => <span>Last Name</span>,
    footer: (info) => info.column.id,
  }),
  columnHelper.accessor('age', {
    header: () => 'Age',
    cell: (info) => info.renderValue(),
    footer: (info) => info.column.id,
  }),
  columnHelper.accessor('visits', {
    header: () => <span>Visits</span>,
    footer: (info) => info.column.id,
  }),
  columnHelper.accessor('status', {
    header: 'Status',
    footer: (info) => info.column.id,
  }),
  columnHelper.accessor('progress', {
    header: 'Profile Progress',
    footer: (info) => info.column.id,
  }),
];

function App() {
  const table = useReactTable({
    data: defaultData,
    columns,
    getCoreRowModel: getCoreRowModel(),
  });

  return (
    <div className="p-2">
      <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>
        <tfoot>
          {table.getFooterGroups().map((footerGroup) => (
            <tr key={footerGroup.id}>
              {footerGroup.headers.map((header) => (
                <th key={header.id}>
                  {flexRender(
                    header.column.columnDef.footer,
                    header.getContext()
                  )}
                </th>
              ))}
            </tr>
          ))}
        </tfoot>
      </table>
    </div>
  );
}

🧱 结构速览

tsx 复制代码
type Person = { ... } // 数据类型定义

const defaultData: Person[] = [ ... ] // 原始数据

const columnHelper = createColumnHelper<Person>(); // 创建列辅助器

const columns = [ ... ] // 定义表格的列

const table = useReactTable({
  data: defaultData,
  columns,
  getCoreRowModel: getCoreRowModel(),
});

return (
  <table>
    <thead>...</thead>
    <tbody>...</tbody>
    <tfoot>...</tfoot>
  </table>
);

看过去觉得,好像写了挺多东西?没关系,我们来一个个解构。

🔍 第一步:定义数据类型 & 数据源

TypeScript 类型定义,让表格知道数据长什么样

tsx 复制代码
type Person = {
  firstName: string;
  lastName: string;
  age: number;
  visits: number;
  status: string;
  progress: number;
};

定义一些假数据,准备拿来展示用

tsx 复制代码
const defaultData: Person[] = [
  { firstName: 'tanner', lastName: 'linsley', age: 24, ... },
  ...
];

🧰 第二步:定义列(columns)

这里用到了一个 API:createColumnHelper<Person>()

API链接🔗:tanstack.com/table/lates...

🧩 一句话简介: createColumnHelper<T>() 是一个 "列构造器",它帮助你更方便地定义列(columns)的时候自动带上类型,少写代码,少出错。

tsx 复制代码
const columns = [
  columnHelper.accessor('firstName', {
    cell: (info) => info.getValue(), // 如何显示单元格
    footer: (info) => info.column.id, // 如何显示页脚
  }),
  ...
];

特别注意:有些列是通过 accessor 函数自定义的,比如:

tsx 复制代码
columnHelper.accessor((row) => row.lastName, {
  id: 'lastName',
  ...
})

这样可以灵活处理你希望"用函数方式"生成的列值。

⚙️ 第三步:创建表格对象

tsx 复制代码
const table = useReactTable({
  data: defaultData,
  columns,
  getCoreRowModel: getCoreRowModel(), // 获取核心行模型
});

这一步是表格的"大脑"。它生成一个 table 对象,这个对象里包含了所有你需要渲染的东西:头部、行、单元格、页脚等。

🧱 第四步:渲染表格

表格渲染(也就是把 table 对象渲染成 HTML 的部分)涉及一些不熟悉的新 API

  • table.getHeaderGroups()

  • header.isPlaceholder

  • header.getContext()

  • row.getVisibleCells()

  • cell.getContext()

  • flexRender(...)

表格渲染结构总览 这是你现在看到的代码:

tsx 复制代码
<table>
  <thead>
    {table.getHeaderGroups().map(...)}
  </thead>
  <tbody>
    {table.getRowModel().rows.map(...)}
  </tbody>
  <tfoot>
    {table.getFooterGroups().map(...)}
  </tfoot>
</table>

它其实就是三个部分:

  • <thead>渲染表头

  • <tbody>渲染每一行数据

  • <tfoot>渲染页脚

<thead>:渲染页头

tsx 复制代码
<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>

🔍 逐行解析:

table.getHeaderGroups()

→ 获取的是"分组表头",支持多层嵌套列。返回一个数组,每一项对应 <tr>

headerGroup.headers

→ 每个 headerGroup 包含一个 headers 数组,每项对应 <th>

flexRender(...)

→ 表格组件的万能"渲染器":不管你写的是 JSX 还是字符串,都会统一渲染出来。

header.getContext()

→ 给 flexRender() 提供上下文数据(比如列信息、排序状态等)。

<tbody>:渲染数据行

tsx 复制代码
<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.getRowModel().rows

→ 获取所有可见的行数据。

row.getVisibleCells()

→ 每一行对应哪些单元格(即哪些列)。

cell.column.columnDef.cell

→ 当前 cell(单元格)应该如何渲染,取决于你在 columns 中定义的 cell 属性。

cell.getContext()

→ 提供当前单元格的上下文环境(比如 row data 等)。

flexRender(...)

→ 再次登场!万能渲染函数。它负责把你写的 JSX、函数、字符串等都正确渲染成 HTML。

<tfoot>:渲染页脚

tsx 复制代码
<tfoot>
  {table.getFooterGroups().map((footerGroup) => (
    <tr key={footerGroup.id}>
      {footerGroup.headers.map((header) => (
        <th key={header.id}>
          {flexRender(header.column.columnDef.footer, header.getContext())}
        </th>
      ))}
    </tr>
  ))}
</tfoot>

页脚的结构和表头几乎一样,只不过渲染的是你在 columns 中写的 footer 属性,比如:

footer: (info) => info.column.id

🎉 最终效果

你将会看到一个整齐的原始表格,包括头部、数据行、页脚。虽然外观看起来比较"朴素",但结构非常灵活,为后续拓展分页、排序、筛选等功能打下基础。

相关推荐
前端老宋Running7 分钟前
一次从“卡顿地狱”到“丝般顺滑”的 React 搜索优化实战
前端·react.js·掘金日报
隔壁的大叔7 分钟前
如何自己构建一个Markdown增量渲染器
前端·javascript
用户4445543654269 分钟前
Android的自定义View
前端
WILLF10 分钟前
HTML iframe 标签
前端·javascript
枫,为落叶27 分钟前
Axios使用教程(一)
前端
小章鱼学前端32 分钟前
2025 年最新 Fabric.js 实战:一个完整可上线的图片选区标注组件(含全部源码).
前端·vue.js
ohyeah33 分钟前
JavaScript 词法作用域、作用域链与闭包:从代码看机制
前端·javascript
流星稍逝35 分钟前
手搓一个简简单单进度条
前端
倚栏听风雨1 小时前
详解 TypeScript 中,async 和 await
前端
4***14901 小时前
TypeScript在React中的前端框架
react.js·typescript·前端框架