TanStack Table V8 是基于 TypeScript 对 React Table v7 进行的全面重写。您的标记和 CSS 的整体结构/组织方式基本保持不变,但许多 API 已被重命名或替换。
新版 TanStack Table 发布在 @tanstack 作用域下。使用您喜欢的包管理器安装新包:
npm uninstall react-table @types/react-table
npm install @tanstack/react-table
npm uninstall react-table @types/react-table
npm install @tanstack/react-table
- 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 包。两个版本的包可以并存,分别用于不同的表格而不会产生冲突。
- 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 ++]
const columns = [
- { // [!code --]
- accessor: 'firstName', // [!code --]
- Header: 'First Name', // [!code --]
- }, // [!code --]
- { // [!code --]
- accessor: row => row.lastName, // [!code --]
- Header: () => <span>Last Name</span>, // [!code --]
- }, // [!code --]
// 最佳 TypeScript 体验,特别在使用 `cell.getValue()` 时
+ columnHelper.accessor('firstName', { //accessorKey // [!code ++]
+ header: 'First Name', // [!code ++]
+ }), // [!code ++]
+ columnHelper.accessor(row => row.lastName, { //accessorFn // [!code ++]
+ header: () => <span>Last Name</span>, // [!code ++]
+ }), // [!code ++]
// 或(如果偏好)
+ { // [!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 --]
// 最佳 TypeScript 体验,特别在使用 `cell.getValue()` 时
+ columnHelper.accessor('firstName', { //accessorKey // [!code ++]
+ header: 'First Name', // [!code ++]
+ }), // [!code ++]
+ columnHelper.accessor(row => row.lastName, { //accessorFn // [!code ++]
+ header: () => <span>Last Name</span>, // [!code ++]
+ }), // [!code ++]
// 或(如果偏好)
+ { // [!code ++]
+ accessorKey: 'firstName', // [!code ++]
+ header: 'First Name', // [!code ++]
+ }, // [!code ++]
+ { // [!code ++]
+ accessorFn: row => row.lastName, // [!code ++]
+ header: () => <span>Last Name</span>, // [!code ++]
+ }, // [!code ++]
]
注意:在组件内定义列时,仍应为列定义保持稳定标识。这有助于性能优化并避免不必要的重新渲染。将列定义存储在 useMemo 或 useState 钩子中。
列选项名称变更
自定义单元格渲染器变更
- <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 ++]
- <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 ++]
// 此场景下的列定义示例
- 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 ++]
// 此场景下的列定义示例
- 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 ++]
- (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 ++]
本指南仍在完善中。如有时间,欢迎贡献您的经验!
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.