框架
版本
企业版

迁移到 V8 指南

迁移到 V8

TanStack Table V8 是 React Table v7 的一个重大重写版本,从头开始使用 TypeScript 构建。您的标记和 CSS 的总体结构/组织将基本保持不变,但许多 API 已被重命名或替换。

显著变化

  • 完全重写为 TypeScript,类型包含在基础包中
  • 移除插件系统,以支持更多的控制反转
  • 更大且改进的 API(以及新的功能,如固定)
  • 更好的受控状态管理
  • 更好地支持服务器端操作
  • 完整(但可选)的数据管道控制
  • 与框架无关的核心,具有 React、Solid、Svelte、Vue 和未来可能更多的框架适配器
  • 新的开发工具

安装新版本

新版本的 TanStack Table 发布在 @tanstack 作用域下。使用您喜欢的包管理器安装新包

bash
npm uninstall react-table @types/react-table
npm install @tanstack/react-table
npm uninstall react-table @types/react-table
npm install @tanstack/react-table
tsx
- import { useTable } from 'react-table' // [!code --]
+ import { useReactTable } from '@tanstack/react-table' // [!code ++]
- import { useTable } from 'react-table' // [!code --]
+ import { useReactTable } from '@tanstack/react-table' // [!code ++]

类型现在包含在基础包中,因此您可以删除 @types/react-table 包。

如果您愿意,您可以保留旧的 react-table 包,以便您可以逐步迁移您的代码。您应该能够并行使用这两个包,用于单独的表格,而不会出现任何问题。

更新表格选项

  • useTable 重命名为 useReactTable
  • 旧的 Hook 和插件系统已被移除,但它们已被每个功能的可摇树优化的行模型导入所取代。
tsx
- import { useTable, usePagination, useSortBy } from 'react-table'; // [!code --]
+ import { // [!code ++]
+   useReactTable, // [!code ++]
+   getCoreRowModel, // [!code ++]
+   getPaginationRowModel, // [!code ++]
+   getSortedRowModel // [!code ++]
+ } from '@tanstack/react-table'; // [!code ++]

// ...

-   const tableInstance = useTable( // [!code --]
-     { columns,  data }, // [!code --]
-     useSortBy, // [!code --]
-     usePagination, //order of hooks used to matter // [!code --]
-     // etc. // [!code --]
-   ); // [!code --]
+   const tableInstance = useReactTable({ // [!code ++]
+     columns, // [!code ++]
+     data, // [!code ++]
+     getCoreRowModel: getCoreRowModel(), // [!code ++]
+     getPaginationRowModel: getPaginationRowModel(), // [!code ++]
+     getSortedRowModel: getSortedRowModel(), //order doesn't matter anymore! // [!code ++]
+     // etc. // [!code ++]
+   }); // [!code ++]
- import { useTable, usePagination, useSortBy } from 'react-table'; // [!code --]
+ import { // [!code ++]
+   useReactTable, // [!code ++]
+   getCoreRowModel, // [!code ++]
+   getPaginationRowModel, // [!code ++]
+   getSortedRowModel // [!code ++]
+ } from '@tanstack/react-table'; // [!code ++]

// ...

-   const tableInstance = useTable( // [!code --]
-     { columns,  data }, // [!code --]
-     useSortBy, // [!code --]
-     usePagination, //order of hooks used to matter // [!code --]
-     // etc. // [!code --]
-   ); // [!code --]
+   const tableInstance = useReactTable({ // [!code ++]
+     columns, // [!code ++]
+     data, // [!code ++]
+     getCoreRowModel: getCoreRowModel(), // [!code ++]
+     getPaginationRowModel: getPaginationRowModel(), // [!code ++]
+     getSortedRowModel: getSortedRowModel(), //order doesn't matter anymore! // [!code ++]
+     // etc. // [!code ++]
+   }); // [!code ++]
  • 所有 disable* 表格选项都已重命名为 enable* 表格选项。(例如,disableSortBy 现在是 enableSortingdisableGroupBy 现在是 enableGrouping 等)
  • ...

更新列定义

  • accessor 已重命名为 accessorKeyaccessorFn (取决于您使用的是字符串还是函数)
  • width、minWidth、maxWidth 已重命名为 size、minSize、maxSize
  • 可选地,您可以对每个列定义使用新的 createColumnHelper 函数,以获得更好的 TypeScript 提示。(如果您愿意,您仍然可以使用列定义的数组。)
    • 第一个参数是访问器函数或访问器字符串。
    • 第二个参数是列选项的对象。
tsx
const columns = [
-  { // [!code --]
-    accessor: 'firstName', // [!code --]
-    Header: 'First Name', // [!code --]
-  }, // [!code --]
-  { // [!code --]
-    accessor: row => row.lastName, // [!code --]
-    Header: () => <span>Last Name</span>, // [!code --]
-  }, // [!code --]

// Best TypeScript experience, especially when using `cell.getValue()` later on
+  columnHelper.accessor('firstName', { //accessorKey // [!code ++]
+    header: 'First Name', // [!code ++]
+  }), // [!code ++]
+  columnHelper.accessor(row => row.lastName, { //accessorFn // [!code ++]
+    header: () => <span>Last Name</span>, // [!code ++]
+  }), // [!code ++]

// OR (if you prefer)
+ { // [!code ++]
+   accessorKey: 'firstName', // [!code ++]
+   header: 'First Name', // [!code ++]
+ }, // [!code ++]
+ { // [!code ++]
+   accessorFn: row => row.lastName, // [!code ++]
+   header: () => <span>Last Name</span>, // [!code ++]
+ }, // [!code ++]
]
const columns = [
-  { // [!code --]
-    accessor: 'firstName', // [!code --]
-    Header: 'First Name', // [!code --]
-  }, // [!code --]
-  { // [!code --]
-    accessor: row => row.lastName, // [!code --]
-    Header: () => <span>Last Name</span>, // [!code --]
-  }, // [!code --]

// Best TypeScript experience, especially when using `cell.getValue()` later on
+  columnHelper.accessor('firstName', { //accessorKey // [!code ++]
+    header: 'First Name', // [!code ++]
+  }), // [!code ++]
+  columnHelper.accessor(row => row.lastName, { //accessorFn // [!code ++]
+    header: () => <span>Last Name</span>, // [!code ++]
+  }), // [!code ++]

// OR (if you prefer)
+ { // [!code ++]
+   accessorKey: 'firstName', // [!code ++]
+   header: 'First Name', // [!code ++]
+ }, // [!code ++]
+ { // [!code ++]
+   accessorFn: row => row.lastName, // [!code ++]
+   header: () => <span>Last Name</span>, // [!code ++]
+ }, // [!code ++]
]

注意:如果在组件内部定义列,您仍然应该尝试为列定义提供稳定的标识。这将有助于性能并防止不必要的重新渲染。将列定义存储在 useMemouseState Hook 中。

  • 列选项名称更改

    • Header 已重命名为 header
    • Cell 已重命名为 cell(单元格渲染函数也已更改。请参阅下文)
    • Footer 已重命名为 footer
    • 所有 disable* 列选项都已重命名为 enable* 列选项。(例如,disableSortBy 现在是 enableSortingdisableGroupBy 现在是 enableGrouping 等)
    • sortType sortingFn
    • ...
  • 自定义单元格渲染器的更改

    • value 已重命名为 getValue(在整个升级过程中,不是直接提供值,而是公开一个函数 getValue 用于评估值。此更改旨在通过仅在调用 getValue() 时评估值,然后缓存它来提高性能。)
    • cell: { isGrouped, isPlaceholder, isAggregated } 现在是 cell: { getIsGrouped, getIsPlaceholder, getIsAggregated }
    • column:基本级别的 props 现在是 RT 特定的。当您定义它时添加到对象的 Value 现在在 columnDef 中更深一层。
    • table:传递到 useTable Hook 中的 Props 现在出现在 options 下。

迁移表格标记

  • 使用 flexRender() 而不是 cell.render('Cell')column.render('Header') 等。
  • getHeaderPropsgetFooterPropsgetCellPropsgetRowProps 等都已弃用
    • TanStack Table 不再提供任何默认的 style 或可访问性属性,如 role。这些对于您正确设置仍然很重要,但为了支持框架无关性,必须将其删除。
    • 您需要手动定义 onClick 处理程序,但有新的 get*Handler 助手来简化此操作。
    • 您需要手动定义 key 属性
    • 如果使用需要它的功能(分组表头、聚合等),您将需要手动定义 colSpan 属性
tsx
- <th {...header.getHeaderProps()}>{cell.render('Header')}</th> // [!code --]
+ <th colSpan={header.colSpan} key={column.id}> // [!code ++]
+   {flexRender( // [!code ++]
+     header.column.columnDef.header, // [!code ++]
+     header.getContext() // [!code ++]
+   )} // [!code ++]
+ </th> // [!code ++]
- <th {...header.getHeaderProps()}>{cell.render('Header')}</th> // [!code --]
+ <th colSpan={header.colSpan} key={column.id}> // [!code ++]
+   {flexRender( // [!code ++]
+     header.column.columnDef.header, // [!code ++]
+     header.getContext() // [!code ++]
+   )} // [!code ++]
+ </th> // [!code ++]
tsx
- <td {...cell.getCellProps()}>{cell.render('Cell')}</td> // [!code --]
+ <td key={cell.id}> // [!code ++]
+   {flexRender( // [!code ++]
+     cell.column.columnDef.cell, // [!code ++]
+     cell.getContext() // [!code ++]
+   )} // [!code ++]
+ </td> // [!code ++]
- <td {...cell.getCellProps()}>{cell.render('Cell')}</td> // [!code --]
+ <td key={cell.id}> // [!code ++]
+   {flexRender( // [!code ++]
+     cell.column.columnDef.cell, // [!code ++]
+     cell.getContext() // [!code ++]
+   )} // [!code ++]
+ </td> // [!code ++]
tsx
// in column definitions in this case
- Header: ({ getToggleAllRowsSelectedProps }) => ( // [!code --]
-   <input type="checkbox" {...getToggleAllRowsSelectedProps()} /> // [!code --]
- ), // [!code --]
- Cell: ({ row }) => ( // [!code --]
-   <input type="checkbox" {...row.getToggleRowSelectedProps()} /> // [!code --]
- ), // [!code --]
+ header: ({ table }) => ( // [!code ++]
+   <Checkbox // [!code ++]
+     checked={table.getIsAllRowsSelected()} // [!code ++]
+     indeterminate={table.getIsSomeRowsSelected()} // [!code ++]
+     onChange={table.getToggleAllRowsSelectedHandler()} // [!code ++]
+   /> // [!code ++]
+ ), // [!code ++]
+ cell: ({ row }) => ( // [!code ++]
+   <Checkbox // [!code ++]
+     checked={row.getIsSelected()} // [!code ++]
+     disabled={!row.getCanSelect()} // [!code ++]
+     indeterminate={row.getIsSomeSelected()} // [!code ++]
+     onChange={row.getToggleSelectedHandler()} // [!code ++]
+   /> // [!code ++]
+ ), // [!code ++]
// in column definitions in this case
- Header: ({ getToggleAllRowsSelectedProps }) => ( // [!code --]
-   <input type="checkbox" {...getToggleAllRowsSelectedProps()} /> // [!code --]
- ), // [!code --]
- Cell: ({ row }) => ( // [!code --]
-   <input type="checkbox" {...row.getToggleRowSelectedProps()} /> // [!code --]
- ), // [!code --]
+ header: ({ table }) => ( // [!code ++]
+   <Checkbox // [!code ++]
+     checked={table.getIsAllRowsSelected()} // [!code ++]
+     indeterminate={table.getIsSomeRowsSelected()} // [!code ++]
+     onChange={table.getToggleAllRowsSelectedHandler()} // [!code ++]
+   /> // [!code ++]
+ ), // [!code ++]
+ cell: ({ row }) => ( // [!code ++]
+   <Checkbox // [!code ++]
+     checked={row.getIsSelected()} // [!code ++]
+     disabled={!row.getCanSelect()} // [!code ++]
+     indeterminate={row.getIsSomeSelected()} // [!code ++]
+     onChange={row.getToggleSelectedHandler()} // [!code ++]
+   /> // [!code ++]
+ ), // [!code ++]

其他变化

  • 自定义 filterTypes(现在称为 filterFns)具有新的函数签名,因为它只返回一个布尔值,指示是否应包含该行。
tsx
- (rows: Row[], id: string, filterValue: any) => Row[] // [!code --]
+ (row: Row, id: string, filterValue: any) => boolean // [!code ++]
- (rows: Row[], id: string, filterValue: any) => Row[] // [!code --]
+ (row: Row, id: string, filterValue: any) => boolean // [!code ++]
  • ...

本指南正在进行中。如果您有时间,请考虑为其做出贡献!

订阅 Bytes

您每周的 JavaScript 新闻。每周一免费发送给超过 10 万名开发者。

Bytes

无垃圾邮件。随时取消订阅。