Log in
Enquire now
React Table

React Table

React Table is a collection of hooks for building powerful tables and datagrid experiences. These hooks are lightweight, composable, and ultra-extensible, but do not render any markup or styles for you. This effectively means that React Table is a "headless" UI library.

OverviewStructured DataIssuesContributors

Contents

react-table.tanstack.com/docs/overview
Is a
Software
Software

What is a "headless" UI library?

React Table is a headless utility, which means out of the box, it doesn't render or supply any actual UI elements. You are in charge of utilizing the state and callbacks of the hooks provided by this library to render your own table markup. Read this article to understand why React Table is built this way. If you don't want to, then here's a quick explanation of why headless UI is important:

  • Separation of Concerns - Not that superficial kind you read about all the time. The real kind. React Table as a library honestly has no business being in charge of your UI. The look, feel, and overall experience of your table is what makes your app or product great. The less React Table gets in the way of that, the better!
  • Maintenance - By removing the massive (and seemingly endless) API surface area required to support every UI use-case, React Table can remain small, easy-to-use and simple to update/maintain.
  • Extensibility - UI presents countless edge cases for a library simply because it's a creative medium, and one where every developer does things differently. By not dictating UI concerns, React Table empowers the developer to design and extend the UI based on their unique use-case.

A Table Utility, not a Table Component

By acting as an ultra-smart table utility, React Table opens up the possibility for your tables to integrate into any existing theme, UI library or existing table markup. This also means that if you don't have an existing table component or table styles, React Table will help you learn to build the table markup and styles required to display great tables.

Installation

You can install React Table with NPM, Yarn, or a good ol'

<script> 

via unpkg.com.

NPM

npm install react-table --save

or

yarn add react-table

React Table is compatible with React v16.8+ and works with ReactDOM and React Native.

Quick Start

At the heart of every React Table is the useTable hook and the table instance object that it returns. This instance object contains everything you'll need to build a table and interact with its state. This includes, but is not limited to:

  • Columns
  • Materialized Data
  • Sorting
  • Filtering
  • Grouping
  • Pagination
  • Expanded State
  • Any functionality provided by custom plugin hooks, too!

In React Table, you the developer are responsible for rendering the UI (markup and styles) of your table, but don't let that intimidate you! Table UIs are fun and React Table exists to make the process much easier to wire up your own table UI.

To show you how this works. Let's start with a very basic table example.

Getting your data

When thinking about a table structure, you typically have rows which contain columns. While table configurations can get far more complex with nested columns, subrows, etc. for this basic quick start, we need to define some data that resembles this structure.

const data = React.useMemo(
   () => [
     {
       col1: 'Hello',
       col2: 'World',
     },
     {
       col1: 'react-table',
       col2: 'rocks',
     },
     {
       col1: 'whatever',
       col2: 'you want',
     },
   ],
   []
 )

It's important that we're using React.useMemo here to ensure that our data isn't recreated on every render. If we didn't use React.useMemo, the table would think it was receiving new data on every render and attempt to recalculate a lot of logic every single time. Not cool!

Define Columns

Now that we have some data, let's create a set of column definitions to pass into the useTable hook.

 const columns = React.useMemo(
   () => [
     {
       Header: 'Column 1',
       accessor: 'col1', // accessor is the "key" in the data
     },
     {
       Header: 'Column 2',
       accessor: 'col2',
     },
   ],
   []
 )

Again, we're using React.useMemo so React Table doesn't recalculate the universe on every single render. Only when the memoized value actually changes!

Using the useTable hook

Now that you have some data and columns defined, we can pass those into the useTable hook to create a table instance.

const tableInstance = useTable({ columns, data })

useTable at the very least needs to be provided with an object containing the memoized columns and data.

Building a basic table UI

Nice! We have our table instance and we're almost there! However, we still don't have any table markup or styles to show, right?

Let's build a basic table structure using just HTML for now:

return (
   <table>
     <thead>
       <tr>
         <th></th>
       </tr>
     </thead>
     <tbody>
       <tr>
         <td></td>
       </tr>
     </tbody>
   </table>
 )

Applying the table instance to markup

Now that we have our table structure, we can use the tableInstance to make it come to life!

const tableInstance = useTable({ columns, data })
 
 const {
   getTableProps,
   getTableBodyProps,
   headerGroups,
   rows,
   prepareRow,
 } = tableInstance
 
 return (
   // apply the table props
   <table {...getTableProps()}>
     <thead>
       {// Loop over the header rows
       headerGroups.map(headerGroup => (
         // Apply the header row props
         <tr {...headerGroup.getHeaderGroupProps()}>
           {// Loop over the headers in each row
           headerGroup.headers.map(column => (
             // Apply the header cell props
             <th {...column.getHeaderProps()}>
               {// Render the header
               column.render('Header')}
             </th>
           ))}
         </tr>
       ))}
     </thead>
     {/* Apply the table body props */}
     <tbody {...getTableBodyProps()}>
       {// Loop over the table rows
       rows.map(row => {
         // Prepare the row for display
         prepareRow(row)
         return (
           // Apply the row props
           <tr {...row.getRowProps()}>
             {// Loop over the rows cells
             row.cells.map(cell => {
               // Apply the cell props
               return (
                 <td {...cell.getCellProps()}>
                   {// Render the cell contents
                   cell.render('Cell')}
                 </td>
               )
             })}
           </tr>
         )
       })}
     </tbody>
   </table>
 )

Final Result

If we put all of this together, we should get a very basic (as well as temporarily ugly) table.

import { useTable } from 'react-table'
 
 function App() {
   const data = React.useMemo(
     () => [
       {
         col1: 'Hello',
         col2: 'World',
       },
       {
         col1: 'react-table',
         col2: 'rocks',
       },
       {
         col1: 'whatever',
         col2: 'you want',
       },
     ],
     []
   )
 
   const columns = React.useMemo(
     () => [
       {
         Header: 'Column 1',
         accessor: 'col1', // accessor is the "key" in the data
       },
       {
         Header: 'Column 2',
         accessor: 'col2',
       },
     ],
     []
   )
 
   const {
     getTableProps,
     getTableBodyProps,
     headerGroups,
     rows,
     prepareRow,
   } = useTable({ columns, data })
 
   return (
     <table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
       <thead>
         {headerGroups.map(headerGroup => (
           <tr {...headerGroup.getHeaderGroupProps()}>
             {headerGroup.headers.map(column => (
               <th
                 {...column.getHeaderProps()}
                 style={{
                   borderBottom: 'solid 3px red',
                   background: 'aliceblue',
                   color: 'black',
                   fontWeight: 'bold',
                 }}
               >
                 {column.render('Header')}
               </th>
             ))}
           </tr>
         ))}
       </thead>
       <tbody {...getTableBodyProps()}>
         {rows.map(row => {
           prepareRow(row)
           return (
             <tr {...row.getRowProps()}>
               {row.cells.map(cell => {
                 return (
                   <td
                     {...cell.getCellProps()}
                     style={{
                       padding: '10px',
                       border: 'solid 1px gray',
                       background: 'papayawhip',
                     }}
                   >
                     {cell.render('Cell')}
                   </td>
                 )
               })}
             </tr>
           )
         })}
       </tbody>
     </table>
   )
 }

Clearly this isn't ready to ship, but from a conceptual standpoint, you just learned the basics of using React Table!

API Overview

React Table uses React Hooks both internally and externally for almost all of its configuration and lifecycle management. Naturally, this is what allows React Table to be headless and lightweight while still having a concise and simple API.

React Table is essentially a compatible collection of custom React hooks:

  • The primary React Table hook

useTable

  • Plugin Hooks

Core Plugin Hooks

useTable

useFilters

useGlobalFilter

useSortBy

useGroupBy

useExpanded

usePagination

useRowSelect

useRowState

useColumnOrder

useResizeColumns

Layout Hooks

useBlockLayout

useAbsoluteLayout

useFlexLayout

  • 3rd Party Plugin Hooks

LineUp-lite Hooks

Core Plugin Hooks

useStats

Column Hooks

useRowExpandColumn

useRowSelectColumn

useRowRankColumn

Numerous renderers for cells, groups, aggregations, and interactive summaries

Want your custom plugin hook listed here? Submit a PR!

Hook Usage

useTable is the primary hook used to build a React Table. It serves as the starting point for every option and every plugin hook that React Table supports. The options passed into useTable are supplied to every plugin hook after it in the order they are supplied, eventually resulting in a final instance object that you can use to build your table UI and interact with the table's state.

const instance = useTable(
   {
     data: [...],
     columns: [...],
   },
   useGroupBy,
   useFilters,
   useSortBy,
   useExpanded,
   usePagination
 )

The stages of React Table and plugins

  1. useTable is called. A table instance is created.
  2. The instance.state is resolved from either a custom user state or an automatically generated one.
  3. A collection of plugin points is created at instance.hooks.
  4. Each plugin is given the opportunity to add hooks to instance.hook.
  5. As the useTable logic proceeds to run, each plugin hook type is used at a specific point in time with each individual hook function being executed the order it was registered.
  6. The final instance object is returned from useTable, which the developer then uses to construct their table.

This multi-stage process is the secret sauce that allows React Table plugin hooks to work together and compose nicely, while not stepping on each others toes.

To dive deeper into plugins, see Plugins and the Plugin Guide

Plugin Hook Order & Consistency

The order and usage of plugin hooks must follow The Laws of Hooks, just like any other custom hook. They must always be unconditionally called in the same order.

NOTE: In the event that you want to programmatically enable or disable plugin hooks, most of them provide options to disable their functionality, eg. options.disableSortBy

Option Memoization

React Table relies on memoization to determine when state and side effects should update or be calculated. This means that every option you pass to useTable should be memoized either via React.useMemo (for objects) or React.useCallback (for functions).

useTable

  • Required

useTable is the root hook for React Table. To use it, pass it with an options object with at least a columns and data value, followed by any React Table compatible hooks you want to use.

Table Options

The following options are supported via the main options object passed to useTable(options)

  • columns: Array<Column>

- Required

- Must be memoized

- The core columns configuration object for the entire table.

- Supports nested columns arrays via the column's columns key, eg. [{ Header: 'My Group', columns: [...] }]

  • data: Array<any>

- Required

- Must be memoized

- The data array that you want to display on the table.

  • initialState: Object

- Optional

- The initial state object for the table.

- Upon table initialization, this object is merged over the table's defaultState object (eg. {...defaultState, ...initialState}) that React Table and its hooks use to register default state to produce the final initial state object passed to the React.useState hook internally.

  • initialState.hiddenColumns: Array<ColumnId: String>

- Optional

- The initial state object for hidden columns

- If a column's ID is contained in this array, it will be hidden

- To update hiddenColumns, pass a new array into setHiddenColumns which is supplied by useTable. Changing hiddenColumns directly won't cause the table to add the hidden columns back.

  • autoResetHiddenColumns: Boolean

- Defaults to true

- When true, the hiddenColumns state will automatically reset if any of the following conditions are met:

columns is changed

- To disable, set to false

  • stateReducer: Function(newState, action, prevState) => newState

- Optional

- With every action that is dispatched to the table's internal React.useReducer instance, this reducer is called and is allowed to modify the final state object for updating.

- It is passed the newState, action, and prevState and is expected to either return the newState or a modified version of the newState

- May also be used to "control" the state of the table, by overriding certain pieces of state regardless of the action.

  • useControlledState: HookFunction(state) => controlledState

- Optional

- If you need to control part of the table state, this is the place to do it.

- This function is run on every single render, just like a hook and allows you to alter the final state of the table if necessary.

- You can use hooks inside of this function, but most of the time, we just suggest using React.useMemo to memoize your state overrides.

- See the FAQ "How can I manually control the table state?" for a an example.

  • defaultColumn: Object

- Optional

- Defaults to {}

- The default column object for every column passed to React Table.

- Column-specific properties will override the properties in this object, eg. { ...defaultColumn, ...userColumn }

- This is particularly useful for adding global column properties. For instance, when using the useFilters plugin hook, add a default Filter renderer for every column, eg.{ Filter: MyDefaultFilterComponent }

  • getSubRows: Function(row, relativeIndex) => Rows[]

- Optional

- Must be memoized

- Defaults to (row) => row.subRows || []

- Use this function to change how React Table detects subrows. You could even use this function to generate sub rows if you want.

- By default, it will attempt to return the subRows property on the row, or an empty array if that is not found.

  • getRowId: Function(row, relativeIndex, ?parent) => string

- Use this function to change how React Table detects unique rows and also how it constructs each row's underlying id property.

- Optional

- Must be memoized

- Defaults to (row, relativeIndex, parent) => parent ? [parent.id, relativeIndex].join('.') : relativeIndex

Column Options

Timeline

No Timeline data yet.

Further Resources

Title
Author
Link
Type
Date

GitHub - TanStack/react-table: ⚛️ Hooks for building fast and extendable tables and datagrids for React

https://github.com/TanStack/react-table

Web

React Table Tutorial - 1 - Introduction

https://www.youtube.com/watch?v=YwP4NAZGskg

Web

October 12, 2020

React Table Tutorial - 10 - More on Filtering

https://www.youtube.com/watch?v=bXq9rmqLqDE

Web

October 21, 2020

React Table Tutorial - 14 - Selecting Rows

https://www.youtube.com/watch?v=e-EFSkq4AaI

Web

November 2, 2020

React Table Tutorial - 17 - Sticky Columns

https://www.youtube.com/watch?v=YgNHon2oKcg

Web

November 4, 2020

References

Find more entities like React Table

Use the Golden Query Tool to find similar entities by any field in the Knowledge Graph, including industry, location, and more.
Open Query Tool
Access by API
Golden Query Tool
Golden logo

Company

  • Home
  • Pricing
  • Enterprise

Legal

  • Terms of Service
  • Enterprise Terms of Service
  • Privacy Policy

Help

  • Help center
  • API Documentation
  • Contact Us
By using this site, you agree to our Terms of Service.