Signup/Sign In
PUBLISHED ON: APRIL 22, 2021

ReactJS Table

Everyone in the Developer community understands Tables UI and accepts that Since it's one of the most effective ways to arrange complicated data in the UI, table UIs are very popular in web products. But along with this trade Tables UI is known for giving developers headaches. Fortunately, there are several resources and libraries available to make building a React table much easier and more enjoyable, the most notable of which is React Table.

This Tutorial is all about making you understand how to use react-table to build a smart React data table UI with simple sorting and searching functionality.

Let's dive straight in.

React Table: Introduction

React Table is one of the most common table libraries in the React ecosystem. The react-table library is extremely lightweight and includes all of the essential functionality for every simple table. React-table is one of our favorites because it's simple to set up, customize, and expand. Sorting, scanning, and pagination are only a few of the features covered in the library.

You should use react-table when:

  • Sorting, browsing, and pagination are all basic functions.
  • UI template for the table that is exclusive without compromising functionality.\
  • Extensibility is simple. Using custom plugin Hooks, you can add your own features to the library.

Use cases for react-table:

  • For simple tables that include only the most basic functions such as scanning, sorting, and filtering.
  • Finance data table with personalized features, sports leaderboards/statistics

React table UI features

Some of the basic features are:

  • Uncompromised user experience and interface. Within the table UI, there is clear typography and custom components.
  • Filtering and sorting choices at a basic level
  • Aid for pagination or infinitely long tables
  • Inline data editing for a column is supported.
  • Columns that can be resized to handle long data points
  • Support for horizontal and vertical scrolling
  • Rows that can be expanded to show all of the details for that row
  • Fixed headers and columns make data easier to read.
  • Support for horizontal and vertical scrolling

React Sandbox: create a React table Component

We'll build a simple table UI with basic features including sorting and searching.

Build a React app first with create-react-app:

npx create-react-app react-table-demo

Now, calling an API with Using Axios, we'll call to get details about the shows using the search word "snow." Let's install Axios so we can use the API:

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;

Adding react-table to React app

To add react-table:

yarn add react-table

React Hooks are used by react-table. It has a useTable key table Hook and a plugin framework for adding plugin Hooks. As a result, the react-table is conveniently extensible to meet our specific requirements. Now for the next step let's create the basic UI with the useTable hook.

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;

We may construct several classes of headers and columns in the columns. We made two different stages.

Let's get done with 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>
  );
}

Our cell values are all strings, and the array values are all translated to comma-separated string values as well. Consider the following scenario:

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

Our App looks like till now:

Let's Add search functionality using useFilters

If you look at the react-table demo website, you'll see that it already has everything you need to make a custom smart table. Just one feature is absent from the demo: global search:

let's start by crating search input in table.js

Table.js

// Create a state
const [filterInput, setFilterInput] = useState("");

// Update the state when input changes
const handleFilterChange = e => {
  const value = e.target.value || undefined;
  setFilterInput(value);
};

// Input element
<input
  value={filterInput}
  onChange={handleFilterChange}
  placeholder={"Search name"}
/>

Now, for passing the filter value to our table and filter rows we use a hook plugin called useFilters:

const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    setFilter // The useFilter Hook provides a way to set the filter
  } = useTable(
    {
      columns,
      data
    },
    useFilters

Time to update our handle interchange function:

const handleFilterChange = e => {
  const value = e.target.value || undefined;
  setFilter("show.name", value); // Update the show.name filter. Now our table will filter and show only the rows which have a matching value
  setFilterInput(value);
};

Finally, our UI will look like this:

Sorting Feature with useSortBy

Enable sorting through all columns. It's the same as filtering: it's really easy. We'll need to install the useSortBy plugin and generate a style to display the sorting icon in the table. It will sort in ascending/descending order for you automatically.

const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    setFilter
  } = useTable(
    {
      columns,
      data
    },
    useFilters,
    useSortBy // This plugin Hook will help to sort our table columns
  );

// Table header styling and props to allow sorting

<th
  {...column.getHeaderProps(column.getSortByToggleProps())}
  className={
    column.isSorted
      ? column.isSortedDesc
        ? "sort-desc"
        : "sort-asc"
      : ""
  }
>
  {column.render("Header")}
</th>

At last, Our UI after implementation will look like this:

Conclusion

We learned how to use React to build a table UI. For simple use cases, it's not difficult to make your own table, but avoid reinventing the wheel wherever possible. I hope you learned a lot from table user interfaces.



About the author:
I like writing content about C/C++, DBMS, Java, Docker, general How-tos, Linux, PHP, Java, Go lang, Cloud, and Web development. I have 10 years of diverse experience in software development. Founder @ Studytonight