Framework
Version
Enterprise

Migrieren zu V8

Migration zu V8

TanStack Table V8 war eine komplette Neuentwicklung von React Table v7 von Grund auf in TypeScript. Die allgemeine Struktur/Organisation Ihres Markups und CSS wird weitgehend gleich bleiben, aber viele der APIs wurden umbenannt oder ersetzt.

Bemerkenswerte Änderungen

  • Komplette Neuentwicklung in TypeScript mit im Basis-Paket enthaltenen Typen
  • Entfernung des Plugin-Systems zugunsten stärkerer Inversion of Control
  • Wesentlich größere und verbesserte API (und neue Funktionen wie Pinning)
  • Bessere kontrollierte Zustandsverwaltung
  • Bessere Unterstützung für serverseitige Operationen
  • Vollständige (aber optionale) Steuerung der Datenpipeline
  • Agnostischer Kern mit Framework-Adaptern für React, Solid, Svelte, Vue und potenziell mehr in der Zukunft
  • Neue Dev Tools

Installieren Sie die neue Version

Die neue Version von TanStack Table wird unter dem @tanstack-Scope veröffentlicht. Installieren Sie das neue Paket mit Ihrem bevorzugten Paketmanager

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 ++]

Typen sind jetzt im Basis-Paket enthalten, sodass Sie das Paket @types/react-table entfernen können.

Wenn Sie möchten, können Sie die alten react-table-Pakete installiert lassen, um Ihren Code schrittweise zu migrieren. Sie sollten beide Pakete problemlos nebeneinander für separate Tabellen verwenden können.

Aktualisieren Sie die Tabellenoptionen

  • Benennen Sie useTable in useReactTable um
  • Die alten Hook- und Plugin-Systeme wurden entfernt, aber sie wurden durch baumschüttelbare Row-Model-Importe für jede Funktion ersetzt.
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 ++]
  • Alle disable*-Tabellenoptionen wurden in enable*-Tabellenoptionen umbenannt. (z. B. disableSortBy ist jetzt enableSorting, disableGroupBy ist jetzt enableGrouping usw.)
  • ...

Aktualisieren Sie die Spaltendefinitionen

  • accessor wurde in entweder accessorKey oder accessorFn umbenannt (abhängig davon, ob Sie einen String oder eine Funktion verwenden)
  • width, minWidth, maxWidth wurden in size, minSize, maxSize umbenannt
  • Optional können Sie die neue Funktion createColumnHelper um jede Spaltendefinition verwenden, um bessere TypeScript-Hinweise zu erhalten. (Sie können immer noch einfach ein Array von Spaltendefinitionen verwenden, wenn Sie es vorziehen.)
    • Der erste Parameter ist die Accessor-Funktion oder der Accessor-String.
    • Der zweite Parameter ist ein Objekt mit Spaltenoptionen.
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 ++]
]

Hinweis: Wenn Sie Spalten innerhalb einer Komponente definieren, sollten Sie den Spaltendefinitionen immer noch eine stabile Identität geben. Dies hilft bei der Leistung und verhindert unnötige Neurenderings. Speichern Sie die Spaltendefinitionen entweder in einem useMemo- oder useState-Hook.

  • Namensänderungen bei Spaltenoptionen

    • Header wurde in header umbenannt
    • Cell wurde in cell umbenannt (Die Render-Funktion der Zelle hat sich ebenfalls geändert. Siehe unten)
    • Footer wurde in footer umbenannt
    • Alle disable*-Spaltenoptionen wurden in enable*-Spaltenoptionen umbenannt. (z. B. disableSortBy ist jetzt enableSorting, disableGroupBy ist jetzt enableGrouping usw.)
    • sortType sortingFn
    • ...
  • Änderungen an benutzerdefinierten Zellen-Renderern

    • value wurde in getValue umbenannt (Während des Upgrades wird anstelle der direkten Angabe des Werts eine Funktion getValue bereitgestellt, um den Wert zu evaluieren. Diese Änderung zielt darauf ab, die Leistung zu verbessern, indem der Wert nur ausgewertet wird, wenn getValue() aufgerufen wird, und ihn dann zu cachen.)
    • cell: { isGrouped, isPlaceholder, isAggregated } ist jetzt cell: { getIsGrouped, getIsPlaceholder, getIsAggregated }
    • column: Die Props auf Basisebene sind jetzt RT-spezifisch. Werte, die Sie beim Definieren zum Objekt hinzugefügt haben, befinden sich nun eine Ebene tiefer in columnDef.
    • table: Props, die an den useTable-Hook übergeben wurden, erscheinen nun unter options.

Migrieren Sie das Tabellenmarkup

  • Verwenden Sie flexRender() anstelle von cell.render('Cell') oder column.render('Header') usw.
  • getHeaderProps, getFooterProps, getCellProps, getRowProps usw. sind alle *veraltet*.
    • TanStack Table liefert keine Standard-style- oder Zugänglichkeitsattribute wie role mehr. Diese sind für Sie immer noch wichtig, mussten aber entfernt werden, um die Framework-Unabhängigkeit zu unterstützen.
    • Sie müssen onClick-Handler manuell definieren, aber es gibt neue get*Handler-Helfer, um dies einfach zu halten.
    • Sie müssen die key-Props manuell definieren
    • Sie müssen die colSpan-Prop manuell definieren, wenn Sie Funktionen verwenden, die sie erfordern (gruppierte Header, Aggregation usw.)
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 ++]

Weitere Änderungen

  • Benutzerdefinierte filterTypes (jetzt filterFns genannt) haben eine neue Funktionssignatur, da sie nur einen booleschen Wert zurückgeben, ob die Zeile einbezogen werden soll oder nicht.
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 ++]
  • ...

Diese Anleitung ist noch in Arbeit. Bitte erwägen Sie, dazu beizutragen, wenn Sie Zeit haben!

Unsere Partner
Code Rabbit
AG Grid
Bytes abonnieren

Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kündbar.

Bytes abonnieren

Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kündbar.