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-tableinstalados 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
useTableauseReactTable - 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 tablaenable*. (ej.disableSortByahora esenableSorting,disableGroupByahora esenableGrouping, etc.)
Actualizar definiciones de columna
accessorfue renombrado aaccessorKeyoaccessorFn(dependiendo de si estás usando una cadena o una función)width,minWidth,maxWidthfueron renombrados asize,minSize,maxSize- Opcionalmente, puedes usar la nueva función
createColumnHelperalrededor 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
useMemoouseState.
-
Cambios en los Nombres de las Opciones de Columna
Headerfue renombrado aheaderCellfue renombrado acell(La función de renderizado de celda también ha cambiado. Ver abajo)Footerfue renombrado afooter- Todas las opciones de columna
disable*fueron renombradas a opciones de columnaenable*. (ej.disableSortByahora esenableSorting,disableGroupByahora esenableGrouping, etc.) sortTypeasortingFn- ...
-
Cambios en los renderizadores de celdas personalizados
valuefue renombrado agetValue(A lo largo de la actualización, en lugar de proporcionar el valor directamente, se expone una funcióngetValuepara evaluar el valor. Este cambio tiene como objetivo mejorar el rendimiento evaluando el valor solo cuando se llama agetValue()y luego almacenándolo en caché.)cell: { isGrouped, isPlaceholder, isAggregated }ahora escell: { 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 encolumnDef.table: Las props pasadas al hookuseTableahora aparecen bajooptions.
Migrar el Marcado de la Tabla
- Usa
flexRender()en lugar decell.render('Cell')ocolumn.render('Header'), etc. getHeaderProps,getFooterProps,getCellProps,getRowProps, etc. han sido todos deprecados.- TanStack Table ya no proporciona ningún
stylepredeterminado o atributos de accesibilidad comorole. 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
onClickmanualmente, pero hay nuevas funciones de ayudaget*Handlerpara mantener esto simple. - Necesitarás definir las props
keymanualmente - Necesitarás definir la prop
colSpanmanualmente si usas características que lo requieran (encabezados agrupados, agregación, etc.)
- TanStack Table ya no proporciona ningún
- <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
filterTypespersonalizados (ahora llamadosfilterFns) 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!