Copiar enlace

React Tanstack Table

React Tanstack Table o antes llamado React Table es una biblioteca para poder crear Tablas en un frontend de React. De hecho React Tanstack Table es una biblioteca Headless, lo que significa que no trae estilos ni todos los componentes hechos sino que te da las funcionalidades por partes para que las importes a medida que te hagan falta.

Creación del Proyecto con React Tanstack Table

npm create vite
npm install @tanstack/react-table

Con el proyecto creado, ahora creemos una componente que muestre una tabla sencilla en src/components/SimpleTable.jsx

Datos de ejemplo

Para los datos de ejemplo, podemos usar mockaro

Creacion de Primer Tabla

import {
  flexRender,
  useReactTable,
  getCoreRowModel,
} from "@tanstack/react-table";
import data from "../MOCK_DATA.json";

function SimpleTable() {
  const columns = [
    {
      header: "ID",
      accessorKey: "id",
      footer: "ID",
    },
    {
      header: "First Name",
      accessorKey: "name",
      footer: "First Name",
    },
    {
      header: "Last Name",
      accessorKey: "lastname",
      footer: "Last Name",
    },
    {
      header: "Email",
      accessorKey: "email",
      footer: "Email",
    },
    {
      header: "Date of Birth",
      accessorKey: "dateOfBirth",
      footer: "Date of Birth",
    },
    {
      header: "Country",
      accessorKey: "country",
      footer: "Country",
    },
  ];

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
  });

  return (
    <div>
      <table>
        <thead>
          {table.getHeaderGroups().map((headerGroup) => (
            <tr key={headerGroup.id}>
              {headerGroup.headers.map((header) => (
                <th key={header.id}>
                  {flexRender(
                    header.column.columnDef.header,
                    header.getContext()
                  )}
                </th>
              ))}
            </tr>
          ))}
        </thead>

        <tbody>
          {table.getRowModel().rows.map((row) => (
            <tr key={row.id}>
              {row.getVisibleCells().map((cell) => (
                <td key={cell.id}>
                  {flexRender(cell.column.columnDef.cell, cell.getContext())}
                </td>
              ))}
            </tr>
          ))}
        </tbody>

        <tfoot>
          {table.getFooterGroups().map((footerGroup) => (
            <tr key={footerGroup.id}>
              {footerGroup.headers.map((header) => (
                <th key={header.id}>
                  {flexRender(
                    header.column.columnDef.header,
                    header.getContext()
                  )}
                </th>
              ))}
            </tr>
          ))}
        </tfoot>
      </table>
    </div>
  );
}
export default SimpleTable;

Añadir los estilos

body {
  padding: 7rem;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
  width: 100%;
  border: 1px solid #ddd;
}

thead, tfoot {
  background-color: #333;
  color: #fff;
}

th,
td {
  text-align: left;
  padding: 16px;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}

Procesando celdas

Para procesar una celda podemos usar

import dayjs from 'dayjs'

    {
      header: "Date of Birth",
      accessorKey: "dateOfBirth",
      footer: "Date of Birth",
      cell: info => dayjs(info.value).format('DD/MM/YYYY')
    },

Procesando Filas

ahora si en una sola columna queremos colocar datos que vienen de la fila tambien podemos accederlo:

quitamos la columna name y lastname y lo reemplazamos por:

    {
      header: "FullName",
      accessorFn: row => `${row.name} ${row.lastname}`,
      footer: "FullName",
    },

Segundo Header Group

{
  header: "Fullname",
  columns: [
    {
      header: "First Name",
      accessorKey: "name",
      footer: "First Name",
    },
    {
      header: "Last Name",
      accessorKey: "lastname",
      footer: "Last Name",
    },
  ],
},

Y Luego para que no se muestren los headers por defecto podemos colocar una condicional:

    <thead>
      {table.getHeaderGroups().map((headerGroup) => (
        <tr key={headerGroup.id}>
          {headerGroup.headers.map((header) => (
            <th key={header.id}>
              {header.isPlaceholder
                ? null
                : flexRender(
                    header.column.columnDef.header,
                    header.getContext()
                  )}
            </th>
          ))}
        </tr>
      ))}
    </thead>

Paginacion

import {
  getPaginationRowModel,
} from "@tanstack/react-table";

  const table = useReactTable({
    getPaginationRowModel: getPaginationRowModel(),
  });

<div>
  <button onClick={() => table.setPageIndex(0)}>First Page</button>
  <button
    disabled={!table.getCanPreviousPage()}
    onClick={() => table.previousPage()}
  >
    Previous Page
  </button>
  <button
    disabled={!table.getCanNextPage()}
    onClick={() => table.nextPage()}
  >
    Next Page
  </button>
  <button onClick={() => table.setPageIndex(table.getPageCount() - 1)}>
    Last Page
  </button>
</div>

Ordenamiento de Filas

const [sorting, setSorting] = useState([]); const table = useReactTable({ state: { sorting, }, onSortingChange: setSorting });

      <thead>
      {table.getHeaderGroups().map((headerGroup) => (
        <tr key={headerGroup.id}>
          {headerGroup.headers.map((header) => (
            <th
              key={header.id}
              onClick={header.column.getToggleSortingHandler()}
            >
              {header.isPlaceholder ? null : (
                <div>
                  {flexRender(
                    header.column.columnDef.header,
                    header.getContext()
                  )}
                  {
                    {asc: '⬆️', desc: '⬇️'}[header.column.getIsSorted() ?? null]
                  }
                </div>
              )}
            </th>
          ))}
        </tr>
      ))}
    </thead>

Filtering

const [filtering, setFiltering] = useState("");

const table = useReactTable({ state: { globalFilter: filtering, }, onGlobalFilterChange: setFiltering, });

     <input
    type="text"
    value={filtering}
    onChange={(e) => setFiltering(e.target.value)}
  />

Creacion de componente Reutilizable

El crear una tabla reutilizable no es necesario que la creemos una y otra vez.

Más Recursos

Actualizado por ultima vez el

Aprende a crear tablas con React Tanstack Table, una biblioteca headless para crear tablas

¿Quieres Compatir mi Contenido?

Publicado:hace un año

Actualizado:hace un año