Skip to main content

Guía de Migración a V8

Migración a V8

TanStack Table V8 fue una reescritura importante de React Table v7 desde cero en TypeScript. La estructura/organización general de tu marcado y CSS seguirá siendo en gran medida la misma, pero muchas de las API han sido renombradas o reemplazadas.

Cambios Notables

  • Reescritura completa a TypeScript con tipos incluidos en el paquete base
  • Eliminación del sistema de plugins para favorecer una mayor inversión de control
  • API mucho más grande y mejorada (y nuevas características como el pinning)
  • Gestión del estado mejor controlada
  • Mejor soporte para operaciones del lado del servidor
  • Control completo (pero opcional) de la tubería de datos
  • Núcleo agnóstico con adaptadores de framework para React, Solid, Svelte, Vue, y potencialmente más en el futuro
  • Nuevas Herramientas de Desarrollo

Instalar la nueva Versión

La nueva versión de TanStack Table se publica bajo el ámbito @tanstack. Instala el nuevo paquete usando tu gestor de paquetes favorito:

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

Los tipos ahora están incluidos en el paquete base, por lo que puedes eliminar el paquete @types/react-table.

Si lo deseas, puedes mantener los paquetes antiguos de react-table instalados para que puedas migrar tu código gradualmente. Deberías poder usar ambos paquetes en paralelo para tablas separadas sin ningún problema.

Actualizar Opciones de Tabla

  • Renombrar useTable a useReactTable
  • Los antiguos sistemas de hooks y plugins han sido eliminados, pero han sido reemplazados por importaciones de modelos de fila 'tree-shakable' para cada característica.
- 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, // el orden de los hooks usados importaba // [!code --]
- // etc. // [!code --]
- ); // [!code --]
+ const tableInstance = useReactTable({ // [!code ++]
+ columns, // [!code ++]
+ data, // [!code ++]
+ getCoreRowModel: getCoreRowModel(), // [!code ++]
+ getPaginationRowModel: getPaginationRowModel(), // [!code ++]
+ getSortedRowModel: getSortedRowModel(), // ¡el orden ya no importa! // [!code ++]
+ // etc. // [!code ++]
+ }); // [!code ++]
  • Todas las opciones de tabla disable* fueron renombradas a opciones de tabla enable*. (ej. disableSortBy ahora es enableSorting, disableGroupBy ahora es enableGrouping, etc.)

Actualizar definiciones de columna

  • accessor fue renombrado a accessorKey o accessorFn (dependiendo de si estás usando una cadena o una función)
  • width, minWidth, maxWidth fueron renombrados a size, minSize, maxSize
  • Opcionalmente, puedes usar la nueva función createColumnHelper alrededor de cada definición de columna para mejores sugerencias de TypeScript. (Aún puedes usar un array de definiciones de columna si lo prefieres.)
    • El primer parámetro es la función accessor o la cadena accessor.
    • El segundo parámetro es un objeto de opciones de columna.
const columns = [
- { // [!code --]
- accessor: 'firstName', // [!code --]
- Header: 'First Name', // [!code --]
- }, // [!code --]
- { // [!code --]
- accessor: row => row.lastName, // [!code --]
- Header: () => <span>Last Name</span>, // [!code --]
- }, // [!code --]

// Mejor experiencia TypeScript, especialmente al usar `cell.getValue()` más adelante
+ columnHelper.accessor('firstName', { // accessorKey // [!code ++]
+ header: 'First Name', // [!code ++]
+ }), // [!code ++]
+ columnHelper.accessor(row => row.lastName, { // accessorFn // [!code ++]
+ header: () => <span>Last Name</span>, // [!code ++]
+ }), // [!code ++]

// O (si lo prefieres)
+ { // [!code ++]
+ accessorKey: 'firstName', // [!code ++]
+ header: 'First Name', // [!code ++]
+ }, // [!code ++]
+ { // [!code ++]
+ accessorFn: row => row.lastName, // [!code ++]
+ header: () => <span>Last Name</span>, // [!code ++]
+ }, // [!code ++]
]

Nota: Si defines columnas dentro de un componente, aún deberías intentar dar a las definiciones de columna una identidad estable. Esto ayudará al rendimiento y evitará re-renderizaciones innecesarias. Almacena las definiciones de columna en un hook useMemo o useState.

  • Cambios en los Nombres de las Opciones de Columna

    • Header fue renombrado a header
    • Cell fue renombrado a cell (La función de renderizado de celda también ha cambiado. Ver abajo)
    • Footer fue renombrado a footer
    • Todas las opciones de columna disable* fueron renombradas a opciones de columna enable*. (ej. disableSortBy ahora es enableSorting, disableGroupBy ahora es enableGrouping, etc.)
    • sortType a sortingFn
    • ...
  • Cambios en los renderizadores de celdas personalizados

    • value fue renombrado a getValue (A lo largo de la actualización, en lugar de proporcionar el valor directamente, se expone una función getValue para evaluar el valor. Este cambio tiene como objetivo mejorar el rendimiento evaluando el valor solo cuando se llama a getValue() y luego almacenándolo en caché.)
    • cell: { isGrouped, isPlaceholder, isAggregated } ahora es cell: { getIsGrouped, getIsPlaceholder, getIsAggregated }
    • column: Las props de nivel base ahora son específicas de RT. Los valores que agregaste al objeto al definirlo ahora están un nivel más profundo en columnDef.
    • table: Las props pasadas al hook useTable ahora aparecen bajo options.

Migrar el Marcado de la Tabla

  • Usa flexRender() en lugar de cell.render('Cell') o column.render('Header'), etc.
  • getHeaderProps, getFooterProps, getCellProps, getRowProps, etc. han sido todos deprecados.
    • TanStack Table ya no proporciona ningún style predeterminado o atributos de accesibilidad como role. Estos siguen siendo importantes para que los configures correctamente, pero tuvieron que ser eliminados para poder soportar ser agnóstico del framework.
    • Necesitarás definir los manejadores onClick manualmente, pero hay nuevas funciones de ayuda get*Handler para mantener esto simple.
    • Necesitarás definir las props key manualmente
    • Necesitarás definir la prop colSpan manualmente si usas características que lo requieran (encabezados agrupados, agregación, etc.)
- <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 ++]
// en las definiciones de columna en este caso
- 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 ++]

Otros Cambios

  • Los filterTypes personalizados (ahora llamados filterFns) tienen una nueva firma de función ya que solo devuelven un booleano para indicar si la fila debe ser incluida o no.
- (rows: Row[], id: string, filterValue: any) => Row[] // [!code --]
+ (row: Row, id: string, filterValue: any) => boolean // [!code ++]

Esta guía está en progreso. ¡Por favor, considera contribuir a ella si tienes tiempo!