跟着官方示例学习 @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

🎉 最终效果

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

相关推荐
_r0bin_2 小时前
前端面试准备-7
开发语言·前端·javascript·fetch·跨域·class
IT瘾君2 小时前
JavaWeb:前端工程化-Vue
前端·javascript·vue.js
potender2 小时前
前端框架Vue
前端·vue.js·前端框架
站在风口的猪11083 小时前
《前端面试题:CSS预处理器(Sass、Less等)》
前端·css·html·less·css3·sass·html5
程序员的世界你不懂3 小时前
(9)-Fiddler抓包-Fiddler如何设置捕获Https会话
前端·https·fiddler
MoFe13 小时前
【.net core】天地图坐标转换为高德地图坐标(WGS84 坐标转 GCJ02 坐标)
java·前端·.netcore
去旅行、在路上4 小时前
chrome使用手机调试触屏web
前端·chrome
Aphasia3114 小时前
模式验证库——zod
前端·react.js
lexiangqicheng5 小时前
es6+和css3新增的特性有哪些
前端·es6·css3
拉不动的猪6 小时前
都25年啦,还有谁分不清双向绑定原理,响应式原理、v-model实现原理
前端·javascript·vue.js