Skip to main content

Guía de Ordenamiento

Ejemplos

¿Quieres saltar a la implementación? Echa un vistazo a estos ejemplos:

API

API de Ordenamiento

Guía de Ordenamiento

TanStack Table proporciona soluciones para casi cualquier caso de uso de ordenamiento que puedas tener. Esta guía te llevará a través de las diversas opciones que puedes usar para personalizar la funcionalidad de ordenamiento del lado del cliente incorporada, así como la forma de optar por no usar el ordenamiento del lado del cliente en favor del ordenamiento manual del lado del servidor.

Estado de Ordenamiento

El estado de ordenamiento se define como un array de objetos con la siguiente forma:

type ColumnSort = {
id: string;
desc: boolean;
};
type SortingState = ColumnSort[];

Dado que el estado de ordenamiento es un array, es posible ordenar por varias columnas a la vez. Lee más sobre las personalizaciones de multi-ordenamiento más abajo.

Accediendo al Estado de Ordenamiento

Puedes acceder al estado de ordenamiento directamente desde la instancia de la tabla, al igual que cualquier otro estado, usando la API table.getState().

const table = useReactTable({
columns,
data,
//...
});

console.log(table.getState().sorting); // accede al estado de ordenamiento desde la instancia de la tabla

Sin embargo, si necesitas acceder al estado de ordenamiento antes de que la tabla sea inicializada, puedes "controlar" el estado de ordenamiento como se muestra a continuación.

Estado de Ordenamiento Controlado

Si necesitas un acceso fácil al estado de ordenamiento, puedes controlar/gestionar el estado de ordenamiento en tu propia gestión de estado con las opciones state.sorting y onSortingChange de la tabla.

const [sorting, setSorting] = useState<SortingState>([]); // puede establecer el estado de ordenamiento inicial aquí
//...
// usa el estado de ordenamiento para obtener datos de tu servidor o algo...
//...
const table = useReactTable({
columns,
data,
//...
state: {
sorting,
},
onSortingChange: setSorting,
});

Estado de Ordenamiento Inicial

Si no necesitas controlar el estado de ordenamiento en tu propia gestión de estado o ámbito, pero aún así quieres establecer un estado de ordenamiento inicial, puedes usar la opción initialState de la tabla en lugar de state.

const table = useReactTable({
columns,
data,
//...
initialState: {
sorting: [
{
id: "name",
desc: true, // ordenar por nombre en orden descendente por defecto
},
],
},
});

NOTA: No uses initialState.sorting y state.sorting al mismo tiempo, ya que el estado inicializado en state.sorting anulará a initialState.sorting.

Ordenamiento del Lado del Cliente vs. del Lado del Servidor

Si debes usar el ordenamiento del lado del cliente o del lado del servidor depende completamente de si también estás usando paginación o filtrado del lado del cliente o del lado del servidor. Sé consistente, porque usar el ordenamiento del lado del cliente con paginación o filtrado del lado del servidor solo ordenará los datos que están cargados actualmente, y no el conjunto de datos completo.

Ordenamiento Manual del Lado del Servidor

Si planeas usar tu propio ordenamiento del lado del servidor en tu lógica de back-end, no necesitas proporcionar un modelo de fila ordenado. Pero si has proporcionado un modelo de fila de ordenamiento, pero quieres deshabilitarlo, puedes usar la opción manualSorting de la tabla.

const [sorting, setSorting] = useState < SortingState > [];
//...
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
//getSortedRowModel: getSortedRowModel(), // no es necesario para el ordenamiento manual
manualSorting: true, // usa el modelo de fila pre-ordenado en lugar del modelo de fila ordenado
state: {
sorting,
},
onSortingChange: setSorting,
});

NOTA: Cuando manualSorting se establece en true, la tabla asumirá que los datos que proporcionas ya están ordenados y no aplicará ningún ordenamiento a ellos.

Ordenamiento del Lado del Cliente

Para implementar el ordenamiento del lado del cliente, primero debes proporcionar un modelo de fila de ordenamiento a la tabla. Puedes importar la función getSortedRowModel de TanStack Table, y se utilizará para transformar tus filas en filas ordenadas.

import { useReactTable } from "@tanstack/react-table";
//...
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(), // proporciona un modelo de fila de ordenamiento
});

Funciones de Ordenamiento (Sorting Fns)

La función de ordenamiento predeterminada para todas las columnas se infiere del tipo de datos de la columna. Sin embargo, puede ser útil definir la función de ordenamiento exacta que deseas usar para una columna específica, especialmente si alguno de tus datos es nulo o no es un tipo de datos estándar.

Puedes determinar una función de ordenamiento personalizada por columna usando la opción sortingFn de la columna.

Por defecto, hay 6 funciones de ordenamiento integradas para elegir:

  • alphanumeric - Ordena por valores alfanuméricos mixtos sin distinción entre mayúsculas y minúsculas. Más lento, pero más preciso si tus cadenas contienen números que necesitan ser ordenados naturalmente.
  • alphanumericCaseSensitive - Ordena por valores alfanuméricos mixtos con distinción entre mayúsculas y minúsculas. Más lento, pero más preciso si tus cadenas contienen números que necesitan ser ordenados naturalmente.
  • text - Ordena por valores de texto/cadena sin distinción entre mayúsculas y minúsculas. Más rápido, pero menos preciso si tus cadenas contienen números que necesitan ser ordenados naturalmente.
  • textCaseSensitive - Ordena por valores de texto/cadena con distinción entre mayúsculas y minúsculas. Más rápido, pero menos preciso si tus cadenas contienen números que necesitan ser ordenados naturalmente.
  • datetime - Ordena por tiempo, usa esto si tus valores son objetos Date.
  • basic - Ordena usando una comparación básica/estándar a > b ? 1 : a < b ? -1 : 0. Esta es la función de ordenamiento más rápida, pero puede no ser la más precisa.

También puedes definir tus propias funciones de ordenamiento personalizadas, ya sea como la opción de columna sortingFn o como una función de ordenamiento global usando la opción de tabla sortingFns.

Funciones de Ordenamiento Personalizadas

Al definir una función de ordenamiento personalizada, ya sea en la opción de tabla sortingFns o como opción de columna sortingFn, debe tener la siguiente firma:

// opcionalmente usa SortingFn para inferir los tipos de parámetros
const myCustomSortingFn: SortingFn<TData> = (
rowA: Row<TData>,
rowB: Row<TData>,
columnId: string,
) => {
return; //-1, 0, o 1 - accede a cualquier dato de fila usando rowA.original y rowB.original
};

Nota: La función de comparación no necesita tener en cuenta si la columna está en orden descendente o ascendente. Los modelos de fila se encargarán de esa lógica. Las funciones sortingFn solo necesitan proporcionar una comparación consistente.

Cada función de ordenamiento recibe 2 filas y un ID de columna, y se espera que compare las dos filas usando el ID de columna para devolver -1, 0 o 1 en orden ascendente. Aquí tienes una tabla resumen:

RetornoOrden Ascendente
-1a < b
0a === b
1a > b
const columns = [
{
header: () => "Name",
accessorKey: "name",
sortingFn: "alphanumeric", // usa la función de ordenamiento incorporada por nombre
},
{
header: () => "Age",
accessorKey: "age",
sortingFn: "myCustomSortingFn", // usa la función de ordenamiento global personalizada
},
{
header: () => "Birthday",
accessorKey: "birthday",
sortingFn: "datetime", // recomendado para columnas de fecha
},
{
header: () => "Profile",
accessorKey: "profile",
// usa la función de ordenamiento personalizada directamente
sortingFn: (rowA, rowB, columnId) => {
return rowA.original.someProperty - rowB.original.someProperty;
},
},
];
//...
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
sortingFns: {
// añade una función de ordenamiento personalizada
myCustomSortingFn: (rowA, rowB, columnId) => {
return rowA.original[columnId] > rowB.original[columnId]
? 1
: rowA.original[columnId] < rowB.original[columnId]
? -1
: 0;
},
},
});

Personalizar el Ordenamiento

Hay muchas opciones de tabla y columna que puedes usar para personalizar aún más la experiencia de usuario (UX) y el comportamiento del ordenamiento.

Deshabilitar Ordenamiento

Puedes deshabilitar el ordenamiento para una columna específica o para toda la tabla usando la opción de columna enableSorting o la opción de tabla.

const columns = [
{
header: () => "ID",
accessorKey: "id",
enableSorting: false, // deshabilita el ordenamiento para esta columna
},
{
header: () => "Name",
accessorKey: "name",
},
//...
];
//...
const table = useReactTable({
columns,
data,
enableSorting: false, // deshabilita el ordenamiento para toda la tabla
});

Dirección de Ordenamiento

Por defecto, la primera dirección de ordenamiento al ciclar a través de los estados de ordenamiento para una columna usando las APIs toggleSorting es ascendente para columnas de cadena y descendente para columnas numéricas. Puedes cambiar este comportamiento con la opción de columna sortDescFirst o la opción de tabla.

const columns = [
{
header: () => "Name",
accessorKey: "name",
sortDescFirst: true, // ordenar por nombre en orden descendente primero (el valor predeterminado es ascendente para columnas de cadena)
},
{
header: () => "Age",
accessorKey: "age",
sortDescFirst: false, // ordenar por edad en orden ascendente primero (el valor predeterminado es descendente para columnas numéricas)
},
//...
];
//...
const table = useReactTable({
columns,
data,
sortDescFirst: true, // ordenar por todas las columnas en orden descendente primero (el valor predeterminado es ascendente para columnas de cadena y descendente para columnas numéricas)
});

NOTA: Es posible que quieras establecer explícitamente la opción de columna sortDescFirst en cualquier columna que tenga valores nulos. La tabla podría no ser capaz de determinar correctamente si una columna es un número o una cadena si contiene valores nulos.

Invertir Ordenamiento

Invertir el ordenamiento no es lo mismo que cambiar la dirección de ordenamiento predeterminada. Si la opción de columna invertSorting es true para una columna, entonces los estados de ordenamiento "desc/asc" seguirán ciclando normalmente, pero el ordenamiento real de las filas se invertirá. Esto es útil para valores que tienen una escala invertida de mejor/peor donde los números más bajos son mejores, por ejemplo, una clasificación (1º, 2º, 3º) o una puntuación tipo golf.

const columns = [
{
header: () => "Rank",
accessorKey: "rank",
invertSorting: true, // invierte el ordenamiento para esta columna. 1º -> 2º -> 3º -> ... incluso si se aplica ordenamiento "desc"
},
//...
];

Ordenar Valores Indefinidos

Cualquier valor indefinido se ordenará al principio o al final de la lista según la opción de columna sortUndefined o la opción de tabla. Puedes personalizar este comportamiento para tu caso de uso específico.

Si no se especifica, el valor predeterminado para sortUndefined es 1, y los valores indefinidos se ordenarán con menor prioridad (descendente); si es ascendente, los indefinidos aparecerán al final de la lista.

  • 'first' - Los valores indefinidos se colocarán al principio de la lista.
  • 'last' - Los valores indefinidos se colocarán al final de la lista.
  • false - Los valores indefinidos se considerarán empatados y deberán ser ordenados por el siguiente filtro de columna o índice original (lo que sea aplicable).
  • -1 - Los valores indefinidos se ordenarán con mayor prioridad (ascendente) (si es ascendente, los indefinidos aparecerán al principio de la lista).
  • 1 - Los valores indefinidos se ordenarán con menor prioridad (descendente) (si es ascendente, los indefinidos aparecerán al final de la lista).

NOTA: Las opciones 'first' y 'last' son nuevas en v8.16.0

const columns = [
{
header: () => "Rank",
accessorKey: "rank",
sortUndefined: -1, // 'first' | 'last' | 1 | -1 | false
},
];

Eliminación de Ordenamiento

Por defecto, la capacidad de eliminar el ordenamiento al ciclar a través de los estados de ordenamiento para una columna está habilitada. Puedes deshabilitar este comportamiento usando la opción de tabla enableSortingRemoval. Este comportamiento es útil si quieres asegurar que al menos una columna siempre esté ordenada.

El comportamiento predeterminado al usar las APIs getToggleSortingHandler o toggleSorting es ciclar a través de los estados de ordenamiento de esta manera:

'none' -> 'desc' -> 'asc' -> 'none' -> 'desc' -> 'asc' -> ...

Si deshabilitas la eliminación de ordenamiento, el comportamiento será así:

'none' -> 'desc' -> 'asc' -> 'desc' -> 'asc' -> ...

Una vez que una columna está ordenada y enableSortingRemoval es false, al alternar el ordenamiento en esa columna nunca se eliminará el ordenamiento. Sin embargo, si el usuario ordena por otra columna y no es un evento de multi-ordenamiento, entonces el ordenamiento se eliminará de la columna anterior y solo se aplicará a la nueva columna.

Establece enableSortingRemoval en false si quieres asegurar que al menos una columna siempre esté ordenada.

const table = useReactTable({
columns,
data,
enableSortingRemoval: false, // deshabilita la capacidad de eliminar el ordenamiento en columnas (siempre none -> asc -> desc -> asc)
});

Multi-Ordenamiento

El ordenamiento por múltiples columnas a la vez está habilitado por defecto si se usa la API column.getToggleSortingHandler. Si el usuario mantiene presionada la tecla Shift mientras hace clic en el encabezado de una columna, la tabla ordenará por esa columna además de las columnas que ya están ordenadas. Si usas la API column.toggleSorting, tienes que pasar manualmente si usar o no el multi-ordenamiento. (column.toggleSorting(desc, multi)).

Deshabilitar Multi-Ordenamiento

Puedes deshabilitar el multi-ordenamiento para una columna específica o para toda la tabla usando la opción de columna enableMultiSort o la opción de tabla. Deshabilitar el multi-ordenamiento para una columna específica reemplazará todo el ordenamiento existente con el ordenamiento de la nueva columna.

const columns = [
{
header: () => "Created At",
accessorKey: "createdAt",
enableMultiSort: false, // siempre ordena solo por esta columna si se ordena por esta columna
},
//...
];
//...
const table = useReactTable({
columns,
data,
enableMultiSort: false, // deshabilita el multi-ordenamiento para toda la tabla
});
Personalizar el Disparador de Multi-Ordenamiento

Por defecto, la tecla Shift se usa para disparar el multi-ordenamiento. Puedes cambiar este comportamiento con la opción de tabla isMultiSortEvent. Incluso puedes especificar que todos los eventos de ordenamiento deben disparar el multi-ordenamiento devolviendo true desde la función personalizada.

const table = useReactTable({
columns,
data,
isMultiSortEvent: (e) => true, // un clic normal dispara el multi-ordenamiento
//o
isMultiSortEvent: (e) => e.ctrlKey || e.shiftKey, // también usa la tecla `Ctrl` para disparar el multi-ordenamiento
});
Límite de Multi-Ordenamiento

Por defecto, no hay límite en el número de columnas que se pueden ordenar a la vez. Puedes establecer un límite usando la opción de tabla maxMultiSortColCount.

const table = useReactTable({
columns,
data,
maxMultiSortColCount: 3, // solo permite que 3 columnas se ordenen a la vez
});
Eliminación de Multi-Ordenamiento

Por defecto, la capacidad de eliminar multi-ordenamientos está habilitada. Puedes deshabilitar este comportamiento usando la opción de tabla enableMultiRemove.

const table = useReactTable({
columns,
data,
enableMultiRemove: false, // deshabilita la capacidad de eliminar multi-ordenamientos
});

APIs de Ordenamiento

Existen muchas APIs relacionadas con el ordenamiento que puedes usar para conectar a tu interfaz de usuario u otra lógica. Aquí tienes una lista de todas las APIs de ordenamiento y algunos de sus casos de uso.

  • table.setSorting - Establece el estado de ordenamiento directamente.

  • table.resetSorting - Restablece el estado de ordenamiento al estado inicial o lo borra.

  • column.getCanSort - Útil para habilitar/deshabilitar la interfaz de usuario de ordenamiento para una columna.

  • column.getIsSorted - Útil para mostrar un indicador visual de ordenamiento para una columna.

  • column.getToggleSortingHandler - Útil para conectar la interfaz de usuario de ordenamiento para una columna. Añade a una flecha de ordenamiento (botón de icono), elemento de menú, o simplemente a toda la celda del encabezado de la columna. Este manejador llamará a column.toggleSorting con los parámetros correctos.

  • column.toggleSorting - Útil para conectar la interfaz de usuario de ordenamiento para una columna. Si lo usas en lugar de column.getToggleSortingHandler, tienes que pasar manualmente si usar o no el multi-ordenamiento. (column.toggleSorting(desc, multi))

  • column.clearSorting - Útil para un botón de "borrar ordenamiento" o elemento de menú para una columna específica.

  • column.getNextSortingOrder - Útil para mostrar la dirección en la que la columna se ordenará a continuación. (asc/desc/borrar en un tooltip/elemento de menú/aria-label o algo así).

  • column.getFirstSortDir - Útil para mostrar la dirección en la que la columna se ordenará primero. (asc/desc en un tooltip/elemento de menú/aria-label o algo así).

  • column.getAutoSortDir - Determina si la primera dirección de ordenamiento será ascendente o descendente para una columna.

  • column.getAutoSortingFn - Usado internamente para encontrar la función de ordenamiento predeterminada para una columna si no se especifica ninguna.

  • column.getSortingFn - Devuelve la función de ordenamiento exacta que se está utilizando para una columna.

  • column.getCanMultiSort - Útil para habilitar/deshabilitar la interfaz de usuario de multi-ordenamiento para una columna.

  • column.getSortIndex - Útil para mostrar una insignia o indicador del orden de clasificación de la columna en un escenario de multi-ordenamiento. Es decir, si es la primera, segunda, tercera, etc., columna en ser ordenada.