Skip to main content

Guía de Datos

Guía de Datos

Las tablas comienzan con tus datos. Las definiciones de tus columnas y tus filas dependerán de la forma de tus datos. TanStack Table tiene algunas características de TypeScript que te ayudarán a crear el resto del código de tu tabla con una excelente experiencia de seguridad de tipos. Si configuras tus datos y tipos correctamente, TanStack Table podrá inferir la forma de tus datos y garantizar que las definiciones de tus columnas se hagan correctamente.

TypeScript

TypeScript NO es un requisito para usar los paquetes de TanStack Table... PERO TanStack Table está escrito y organizado de tal manera que la increíble experiencia de TypeScript que obtienes se siente como uno de los principales puntos de venta de la biblioteca. Si no estás utilizando TypeScript, te perderás muchas excelentes características de autocompletado y verificación de tipos que acelerarán tu tiempo de desarrollo y reducirán la cantidad de errores en tu código.

Genéricos de TypeScript

Tener una comprensión básica de qué son y cómo funcionan los Genéricos de TypeScript te ayudará a entender mejor esta guía, pero debería ser bastante fácil de aprender sobre la marcha. La Documentación oficial de Genéricos de TypeScript puede ser útil para aquellos que aún no estén familiarizados con TypeScript.

Definición de Tipos de Datos

data es un array de objetos que se convertirán en las filas de tu tabla. Cada objeto en el array representa una fila de datos (en circunstancias normales). Si estás usando TypeScript, normalmente definimos un tipo para la forma de nuestros datos. Este tipo se usa como un tipo genérico para todas las demás instancias de tabla, columna, fila y celda. Este Genérico se suele denominar TData en el resto de los tipos y APIs de TanStack Table.

Por ejemplo, si tenemos una tabla que muestra una lista de usuarios en un array como este:

[
{
"firstName": "Tanner",
"lastName": "Linsley",
"age": 33,
"visits": 100,
"progress": 50,
"status": "Married"
},
{
"firstName": "Kevin",
"lastName": "Vandy",
"age": 27,
"visits": 200,
"progress": 100,
"status": "Single"
}
]

Entonces podemos definir un tipo User (TData) como este:

//Tipo de datos
type User = {
firstName: string;
lastName: string;
age: number;
visits: number;
progress: number;
status: string;
};

Luego podemos definir nuestro array data con este tipo, y entonces TanStack Table podrá inferir inteligentemente muchos tipos para nosotros más adelante en nuestras columnas, filas, celdas, etc. Esto se debe a que el tipo data se define literalmente como el tipo genérico TData. Lo que sea que pases a la opción data de la tabla se convertirá en el tipo TData para el resto de la instancia de la tabla. Solo asegúrate de que las definiciones de tus columnas utilicen el mismo tipo TData que el tipo data cuando las definas más tarde.

//nota: los datos necesitan una referencia "estable" para evitar re-renders infinitos
const data: User[] = [];
//o
const [data, setData] = React.useState<User[]>([]);
//o
const data = ref<User[]>([]); //para vue
//etc...

Datos con Claves Anidadas

Si tus datos no son un array plano y agradable de objetos, ¡no hay problema! Una vez que llegues a definir tus columnas, existen estrategias para acceder a datos profundamente anidados en tus accessors.

Si tus data se ven algo como esto:

[
{
"name": {
"first": "Tanner",
"last": "Linsley"
},
"info": {
"age": 33,
"visits": 100
}
},
{
"name": {
"first": "Kevin",
"last": "Vandy"
},
"info": {
"age": 27,
"visits": 200
}
}
]

Puedes definir un tipo como este:

type User = {
name: {
first: string;
last: string;
};
info: {
age: number;
visits: number;
};
};

Y podrás acceder a los datos en las definiciones de tus columnas ya sea con notación de puntos en un accessorKey o simplemente usando un accessorFn.

const columns = [
{
header: "Nombre",
accessorKey: "name.first",
},
{
header: "Apellido",
accessorKey: "name.last",
},
{
header: "Edad",
accessorFn: (row) => row.info.age,
},
//...
];

Esto se discute con más detalle en la Guía de Definiciones de Columnas.

NOTA: Las "keys" (claves) en tus datos json pueden ser normalmente cualquier cosa, pero cualquier punto en las claves se interpretará como una clave profunda y causará errores.

Datos Anidados de Subfilas

Si estás utilizando características de expansión, es común tener subfilas anidadas en tus datos. Esto da como resultado un tipo recursivo que es un poco diferente.

Así que si tus datos se ven así:

[
{
"firstName": "Tanner",
"lastName": "Linsley",
"subRows": [
{
"firstName": "Kevin",
"lastName": "Vandy"
},
{
"firstName": "John",
"lastName": "Doe",
"subRows": [
//...
]
}
]
},
{
"firstName": "Jane",
"lastName": "Doe"
}
]

Puedes definir un tipo como este:

type User = {
firstName: string;
lastName: string;
subRows?: User[]; //no tiene que llamarse "subRows", puede llamarse de cualquier manera
};

Donde subRows es un array opcional de objetos User. Esto se discute con más detalle en la Guía de Expansión.

Dar a los Datos una Referencia "Estable"

El array data que pasas a la instancia de la tabla DEBE tener una referencia "estable" para evitar errores que causen re-renders infinitos (especialmente en React).

Esto dependerá del adaptador de framework que estés utilizando, pero en React, a menudo deberías usar React.useState, React.useMemo o similar para asegurar que tanto las opciones de tabla data como columns tengan referencias estables.

const fallbackData = []

export default function MyComponent() {
//✅ BIEN: Esto no causará un bucle infinito de re-renders porque `columns` es una referencia estable
const columns = useMemo(() => [
// ...
], []);

//✅ BIEN: Esto no causará un bucle infinito de re-renders porque `data` es una referencia estable
const [data, setData] = useState(() => [
// ...
]);

// Las columnas y los datos se definen con una referencia estable, ¡no causarán un bucle infinito!
const table = useReactTable({
columns,
data ?? fallbackData, //también es bueno usar un array de reserva que se defina fuera del componente (referencia estable)
});

return <table>...</table>;
}

React.useState y React.useMemo no son las únicas formas de dar a tus datos una referencia estable. También puedes definir tus datos fuera del componente o usar una biblioteca de gestión de estado de terceros como Redux, Zustand o TanStack Query.

Lo principal a evitar es definir el array data dentro del mismo ámbito que la llamada a useReactTable. Eso hará que el array data se redefina en cada renderizado, lo que provocará un bucle infinito de re-renders.

export default function MyComponent() {
//😵 MAL: Esto causará un bucle infinito de re-renders porque `columns` se redefine como un nuevo array en cada renderizado!
const columns = [
// ...
];

//😵 MAL: Esto causará un bucle infinito de re-renders porque `data` se redefine como un nuevo array en cada renderizado!
const data = [
// ...
];

//❌ Las columnas y los datos se definen en el mismo ámbito que `useReactTable` sin una referencia estable, ¡causarán un bucle infinito!
const table = useReactTable({
columns,
data ?? [], //❌ También está mal porque el array de reserva se recrea en cada renderizado
});

return <table>...</table>;
}

Cómo TanStack Table Transforma los Datos

Más adelante, en otras partes de esta documentación, verás cómo TanStack Table procesa los data que pasas a la tabla y genera los objetos de fila y celda que se utilizan para crear la tabla. Los data que pasas a la tabla nunca son mutados por TanStack Table, pero los valores reales en las filas y celdas pueden ser transformados por los accessors en las definiciones de tus columnas, o por otras características realizadas por modelos de fila como la agrupación o la agregación.

¿Cuántos Datos Puede Manejar TanStack Table?

Lo creas o no, TanStack Table fue diseñado para escalar y manejar potencialmente cientos de miles de filas de datos en el cliente. Obviamente, esto no siempre es posible, dependiendo del tamaño de los datos de cada columna y del número de columnas. Sin embargo, las funciones de ordenación, filtrado, paginación y agrupación están todas construidas pensando en el rendimiento para grandes conjuntos de datos.

La mentalidad predeterminada de un desarrollador que construye una cuadrícula de datos es implementar paginación, ordenación y filtrado en el lado del servidor para grandes conjuntos de datos. Esto sigue siendo una buena idea, pero muchos desarrolladores subestiman cuántos datos se pueden manejar realmente en el cliente con los navegadores modernos y las optimizaciones correctas. Si tu tabla nunca tendrá más de unos pocos miles de filas, probablemente puedas aprovechar las funciones del lado del cliente de TanStack Table en lugar de implementarlas tú mismo en el servidor. Antes de comprometerte a dejar que las funciones del lado del cliente de TanStack Table manejen tu gran conjunto de datos, debes probarlo con tus datos reales para ver si funciona lo suficientemente bien para tus necesidades, por supuesto.

Esto se discute con más detalle en la Guía de Paginación.