react js-tutorial

React Table

Because it’s one of the most effective ways to organise complex data in the UI, table UIs are widely used in web products.

It can be difficult to create a table user interface from scratch, and React tables in particular are known to cause developers trouble. React Table is one of the many tools and frameworks that are fortunately available to make the process of constructing a React table much easier and more rewarding.

In this article, we’ll demonstrate how to use react-table to create a smart React data table UI with the bare minimum of sorting and searching capabilities.

What is React Table?

One of the most popular table libraries in React is React Table. At the time of writing, it has more than 13,000 stars on GitHub, is frequently updated, and supports Hooks. The react-table library is fairly compact and provides all the fundamental functionality required for any straightforward table.

React Table v7

React Table v7, which Tanner Linsley, the project’s inventor, referred to as “the conclusion of over a years [sic] worth of work to rework the entire library to a hooks-only UI/Style/Markup neutral table construction tool,” was released in March 2020.

The principal useTable hook of React Table v7 returns a set of React Hooks and Plugins that enable you to combine the logical characteristics of complicated data grids into a single, quick, extendable, and unbiased API.

React Table v7 is a headless tool; it does not render or provide data table UI elements out of the box. It follows that you are in charge of rendering your own table markup utilising the state and callback of the hooks React Table provides.

When to use react-table

When your table UI requires React Table, use it.

  • The fundamental functions of sorting, filtering, and pagination
  • custom user interface without compromising functionality
  • extensibility with ease Using unique plugin Hooks, you can add your own features on top of the library.

When not to use react-table

When you require: Take into account another React data table library.

  • Support for fixed headers and columns by default
  • Support for both horizontal and vertical scrolling out of the box on touch and non-touch devices. Since react-table is headless, it is our obligation to define the UI in accordance with our needs.
  • support for column inline editing. Although we can accomplish it with react-table, our table is unable to do so. To support such functionalities, we must build a plugin or component on top of it. The best method for rendering simple tables is react-table, which keeps true to its name.

React Table example: Building a React table component with react-table

Enough theory — let’s dive into a real React Table example. To demonstrate how to use react-table to create a React table component, we’ll build a simple table UI with basic functionalities such as sorting and searching. Here is the React table example we’ll be working with.

First, create a React app using create-react-app:

npx create-react-app react-table-demo

Calling an API with Axios

This is the API endpoint. We are going to call and fetch the shows’ information with the search term “snow” using Axios.

In order to call the API, let’s install axios:

yarn add axios

App.js

import React, { useState, useEffect } from "react";
import Table from "./Table";
import "./App.css";

function App() {
  // data state to store the TV Maze API data. Its initial value is an empty array
  const [data, setData] = useState([]);

  // Using useEffect to call the API once mounted and set the data
  useEffect(() => {
    (async () => {
      const result = await axios("https://api.tvmaze.com/search/shows?q=snow");
      setData(result.data);
    })();
  }, []);

  return (
    <div className="App"></div>
  );
}

export default App;

We create a state called data, and once the component gets mounted, we call the API using Axios and set the data.

Adding react-table to your app

To add react-table:

yarn add react-table

react-table uses React Hooks. It has a main table Hook called useTable, and it has a plugin system to add plugin Hooks. Thus, react-table is easily extensible based on our custom need.

Let’s create the basic UI with the useTable Hook. We will create a new Table component that will accept two props: data and columns. data is the data we got through the API call, and columns is the object to define the table columns (headers, rows, how the row will be shown, etc.). We will see it in code shortly.

Table.js

export default function Table({ columns, data }) {
// Table component logic and UI come here
}

App.js

import React, { useMemo, useState, useEffect } from "react";
import Table from "./Table";
function App() {
  /* 
    - Columns is a simple array right now, but it will contain some logic later on. It is recommended by react-table to memoize the columns data
    - Here in this example, we have grouped our columns into two headers. react-table is flexible enough to create grouped table headers
  */
  const columns = useMemo(
    () => [
      {
        // first group - TV Show
        Header: "TV Show",
        // First group columns
        columns: [
          {
            Header: "Name",
            accessor: "show.name"
          },
          {
            Header: "Type",
            accessor: "show.type"
          }
        ]
      },
      {
        // Second group - Details
        Header: "Details",
        // Second group columns
        columns: [
          {
            Header: "Language",
            accessor: "show.language"
          },
          {
            Header: "Genre(s)",
            accessor: "show.genres"
          },
          {
            Header: "Runtime",
            accessor: "show.runtime"
          },
          {
            Header: "Status",
            accessor: "show.status"
          }
        ]
      }
    ],
    []
  );

  ...

  return (
    <div className="App">
      <Table columns={columns} data={data} />
    </div>
  );
}

export default App;

Here in the columns, we can create multiple groups of headers and columns. We created two levels.

All the columns also have an accessor, which is the data we have in the data object. Our data is inside the show object in the array — that’s why all our accessors have show. as a prefix.

// sample data array looks like this

[
  {
    "score": 17.592657,
    "show": {
      "id": 44813,
      "url": "http://www.tvmaze.com/shows/44813/the-snow-spider",
      "name": "The Snow Spider",
      "type": "Scripted",
      "language": "English",
      "genres": [
        "Drama",
        "Fantasy"
      ],
      "status": "In Development",
      "runtime": 30,
      "premiered": null,
      "officialSite": null,
      "schedule": {
        "time": "",
        "days": [

        ]
      }
      ...
  },
  {
    // next TV show
  }
...
]

Let’s finish our Table component:

Table.js

import React from "react";
import { useTable } from "react-table";

export default function Table({ columns, data }) {
  // Use the useTable Hook to send the columns and data to build the table
  const {
    getTableProps, // table props from react-table
    getTableBodyProps, // table body props from react-table
    headerGroups, // headerGroups, if your table has groupings
    rows, // rows for the table based on the data passed
    prepareRow // Prepare the row (this function needs to be called for each row before getting the row props)
  } = useTable({
    columns,
    data
  });

  /* 
    Render the UI for your table
    - react-table doesn't have UI, it's headless. We just need to put the react-table props from the Hooks, and it will do its magic automatically
  */
  return (
    <table {...getTableProps()}>
      <thead>
        {headerGroups.map(headerGroup => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map(column => (
              <th {...column.getHeaderProps()}>{column.render("Header")}</th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {rows.map((row, i) => {
          prepareRow(row);
          return (
            <tr {...row.getRowProps()}>
              {row.cells.map(cell => {
                return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
              })}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}


We will pass the columns and data to useTable. The Hook will return the necessary props for the table, body, and transformed data to create the header and cells. The header will be created by iterating through headerGroups, and the rows for the table body will be created by looping through rows.

{rows.map((row, i) => {
  prepareRow(row); // This line is necessary to prepare the rows and get the row props from react-table dynamically

  // Each row can be rendered directly as a string using the react-table render method
  return (
    <tr {...row.getRowProps()}>
      {row.cells.map(cell => {
        return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
      })}
    </tr>
  );
})}

In this way, we rendered the cell and the header. But our cell values are just strings, and even the array values get converted into comma-separated string values. For example:

// Genres array
show.genres = [
 'Comedy',
 'Sci-fi',
]

RECOMMENDED ARTICLES





Leave a Reply

Your email address will not be published.