How to use react-table for advanced tables

TanStack Table (formerly react-table) provides powerful table functionality with sorting, filtering, pagination, and column management without prescribing UI implementation. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented advanced table features with TanStack Table throughout my 11 years of React development. The most effective approach is using the useReactTable hook with column definitions and data to create feature-rich tables. This method offers headless UI flexibility, allowing complete control over table rendering and styling.

Install @tanstack/react-table and use useReactTable hook with column definitions for advanced features.

import { useReactTable, getCoreRowModel, getSortedRowModel, flexRender } from '@tanstack/react-table'
import { useState } from 'react'

const DataTable = () => {
  const data = [
    { id: 1, name: 'John Doe', age: 28, email: '[email protected]' },
    { id: 2, name: 'Jane Smith', age: 34, email: '[email protected]' },
    { id: 3, name: 'Bob Johnson', age: 45, email: '[email protected]' }
  ]

  const columns = [
    { accessorKey: 'id', header: 'ID' },
    { accessorKey: 'name', header: 'Name' },
    { accessorKey: 'age', header: 'Age' },
    { accessorKey: 'email', header: 'Email' }
  ]

  const [sorting, setSorting] = useState([])

  const table = useReactTable({
    data,
    columns,
    state: { sorting },
    onSortingChange: setSorting,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel()
  })

  return (
    <table>
      <thead>
        {table.getHeaderGroups().map(headerGroup => (
          <tr key={headerGroup.id}>
            {headerGroup.headers.map(header => (
              <th key={header.id} onClick={header.column.getToggleSortingHandler()}>
                {flexRender(header.column.columnDef.header, header.getContext())}
                {header.column.getIsSorted() && (header.column.getIsSorted() === 'asc' ? ' 🔼' : ' 🔽')}
              </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>
    </table>
  )
}

Here useReactTable initializes the table instance with data and column definitions. The columns array defines accessorKey for data access and header for display. The sorting state tracks current sort configuration. The getCoreRowModel and getSortedRowModel enable core functionality and sorting. The flexRender function renders headers and cells using column definitions. Clicking headers toggles sorting with visual indicators showing sort direction.

Best Practice Note:

This is the approach we use in CoreUI Pro admin templates for complex data tables with enterprise features. Add pagination with getPaginationRowModel, implement filtering with getFilteredRowModel, and use column visibility controls for user-customizable table layouts with persistent preferences in localStorage.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.

Answers by CoreUI Core Team