How to Use DataTables in React with Tailwind CSS
Tags: react, tailwindcss, webdev, tutorial
Published: 2024-03-25 08:10:24

In this section, we will explore how to integrate DataTables with React applications using Tailwind CSS. We will cover two approaches: utilizing a dedicated library and implementing DataTables without a library. Before we begin, ensure that you have installed and configured Tailwind CSS within your React project.

[Install & Setup Tailwind CSS + React 18+ Typescript + Vite](https://frontendshape.com/post/install-setup-tailwind-css-react-18-typescript-vite)
<br>
To start, we will create a simple user interface for the DataTable using React and Tailwind CSS.
```react
import React from 'react';

const data = [
  { id: 1, name: 'John Doe', email: 'john@example.com' },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com' },
  { id: 3, name: 'Bob Johnson', email: 'bob@example.com' },
];

const DataTable = () => {
  return (
    <div className="flex flex-col container mx-auto">
      <div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
        <div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
          <div className="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
            <table className="min-w-full divide-y divide-gray-200">
              <thead className="bg-gray-50">
                <tr>
                  <th
                    scope="col"
                    className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
                  >
                    ID
                  </th>
                  <th
                    scope="col"
                    className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
                  >
                    Name
                  </th>
                  <th
                    scope="col"
                    className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
                  >
                    Email
                  </th>
                </tr>
              </thead>
              <tbody className="bg-white divide-y divide-gray-200">
                {data.map((item) => (
                  <tr key={item.id}>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <div className="text-sm text-gray-900">{item.id}</div>
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <div className="text-sm text-gray-900">{item.name}</div>
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <div className="text-sm text-gray-900">{item.email}</div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  );
};

export default DataTable;
```
![react tailwind table](https://frontendshape.com/storage/canvas/images/KYcs4m4awg6CjP6I1ZtzeEjF0PcLJlXmaDKZYUxw.png)
Let's build a sortable data table using React and Tailwind CSS.
```react
import React, { useState } from 'react';

const data = [
  { id: 1, name: 'John Doe', email: 'john@example.com', age: 32 },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com', age: 27 },
  { id: 3, name: 'Bob Johnson', email: 'bob@example.com', age: 45 },
];

const SortableDataTable = () => {
  const [sortColumn, setSortColumn] = useState(null);
  const [sortDirection, setSortDirection] = useState(null);

  const handleSort = (column) => {
    if (sortColumn === column) {
      setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc');
    } else {
      setSortColumn(column);
      setSortDirection('asc');
    }
  };

  const sortedData = sortColumn
    ? [...data].sort((a, b) => {
        const valueA = a[sortColumn];
        const valueB = b[sortColumn];

        if (valueA < valueB) return sortDirection === 'asc' ? -1 : 1;
        if (valueA > valueB) return sortDirection === 'asc' ? 1 : -1;
        return 0;
      })
    : data;

  return (
    <div className="flex flex-col">
      <div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
        <div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
          <div className="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
            <table className="min-w-full divide-y divide-gray-200">
              <thead className="bg-gray-50">
                <tr>
                  <th
                    scope="col"
                    className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer"
                    onClick={() => handleSort('id')}
                  >
                    ID
                    {sortColumn === 'id' && (
                      <span>{sortDirection === 'asc' ? ' ↑' : ' ↓'}</span>
                    )}
                  </th>
                  <th
                    scope="col"
                    className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer"
                    onClick={() => handleSort('name')}
                  >
                    Name
                    {sortColumn === 'name' && (
                      <span>{sortDirection === 'asc' ? ' ↑' : ' ↓'}</span>
                    )}
                  </th>
                  <th
                    scope="col"
                    className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer"
                    onClick={() => handleSort('email')}
                  >
                    Email
                    {sortColumn === 'email' && (
                      <span>{sortDirection === 'asc' ? ' ↑' : ' ↓'}</span>
                    )}
                  </th>
                  <th
                    scope="col"
                    className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer"
                    onClick={() => handleSort('age')}
                  >
                    Age
                    {sortColumn === 'age' && (
                      <span>{sortDirection === 'asc' ? ' ↑' : ' ↓'}</span>
                    )}
                  </th>
                </tr>
              </thead>
              <tbody className="bg-white divide-y divide-gray-200">
                {sortedData.map((item) => (
                  <tr key={item.id}>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <div className="text-sm text-gray-900">{item.id}</div>
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <div className="text-sm text-gray-900">{item.name}</div>
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <div className="text-sm text-gray-900">{item.email}</div>
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <div className="text-sm text-gray-900">{item.age}</div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  );
};

export default SortableDataTable;
```
![react tailwind sortable data table](https://frontendshape.com/storage/canvas/images/qoc3gyIEya7V5ruAPZAYElPaQLIiniK9CVQ8tIkR.png)
To create a visually appealing and feature-rich data table in our React application, we will utilize the powerful **react-data-table-component** library and leverage the utility-first classes provided by Tailwind CSS for styling.
<br>
First, you'll need to install the react-data-table-component library:
```
npm install react-data-table-component
```
Then, you can create a new component and import the necessary modules from the library.
```react
import React, { useState } from 'react';
import DataTable from 'react-data-table-component';

const data = [
  { id: 1, name: 'John Doe', email: 'john@example.com', age: 32 },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com', age: 27 },
  { id: 3, name: 'Bob Johnson', email: 'bob@example.com', age: 45 },
  { id: 4, name: 'Alice Williams', email: 'alice@example.com', age: 19 },
  { id: 5, name: 'Tom Davis', email: 'tom@example.com', age: 35 },
  { id: 6, name: 'Sara Lee', email: 'sara@example.com', age: 28 },
];

const columns = [
  {
    name: 'ID',
    selector: (row) => row.id,
    sortable: true,
  },
  {
    name: 'Name',
    selector: (row) => row.name,
    sortable: true,
  },
  {
    name: 'Email',
    selector: (row) => row.email,
    sortable: true,
  },
  {
    name: 'Age',
    selector: (row) => row.age,
    sortable: true,
  },
];

const DataTableExample = () => {
  const [filterText, setFilterText] = useState('');

  const filteredData = data.filter(
    (item) =>
      item.name.toLowerCase().includes(filterText.toLowerCase()) ||
      item.email.toLowerCase().includes(filterText.toLowerCase())
  );

  return (
    <div className="container mx-auto px-4">
      <div className="mb-4">
        <label htmlFor="filter" className="block font-medium text-gray-700">
          Filter:
        </label>
        <input
          type="text"
          id="filter"
          value={filterText}
          onChange={(e) => setFilterText(e.target.value)}
          className="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
        />
      </div>
      <DataTable
        columns={columns}
        data={filteredData}
        pagination
        highlightOnHover
        pointerOnHover
        className="rounded-lg shadow-md"
        customStyles={{
          headRow: {
            style: {
              backgroundColor: '#f3f4f6',
            },
          },
          headCells: {
            style: {
              color: '#4b5563',
              fontSize: '0.875rem',
              fontWeight: 600,
              textTransform: 'uppercase',
            },
          },
          rows: {
            style: {
              '&:nth-of-type(even)': {
                backgroundColor: '#f9fafb',
              },
            },
          },
          cells: {
            style: {
              color: '#374151',
              fontSize: '0.875rem',
            },
          },
        }}
      />
    </div>
  );
};

export default DataTableExample;
```
![react tailwind data-table-component](https://frontendshape.com/storage/canvas/images/zYLiuCYGS55NmkSlroZebJUAAr5tqBXyD3zb86Gu.png)

## See Also
&#x1F449;[React with Tailwind CSS File Upload Example](https://frontendshape.com/post/react-with-tailwind-css-file-upload-example)
&#x1F449;[How to Use Toastify in React with Tailwind CSS](https://frontendshape.com/post/how-to-use-toastify-in-react-with-tailwind-css)
&#x1F449;[Create a Responsive Navbar React Tailwind CSS TypeScript](https://frontendshape.com/post/create-a-responsive-navbar-react-tailwind-css-and-typescript)
&#x1F449;[React TypeScript Tailwind CSS Popup Modal Tutorial](https://frontendshape.com/post/react-typescript-tailwind-css-popup-modal-tutorial)
&#x1F449;[How to Add Drag-and-Drop Image Upload with Dropzone in React Using Tailwind CSS](https://frontendshape.com/post/how-to-add-drag-and-drop-image-upload-with-dropzone-in-react-using-tailwind-css)