In web applications—especially reporting or monitoring applications—we often need to display a large amount of data from an API. To make data loading faster, we typically design our APIs to support pagination.

In classic JavaScript _frameworks like _jQuery, we are familiar with using DataTables to display paginated data tables. But how do we use DataTables in ReactJS?

First, we create react application by executing in our terminal/CMD

npm create-react-app react-demo-datatable

Then in our terminal/CMD we have to install datatable package.

npm install react-data-table-component

Don't forget to install lodash.debounce package for our search data table. lodash.debounce is a utility function from the Lodash library that delays a function’s execution until after a specified amount of time has passed since it was last called. i will prevent Too many API calls (e.g. every user type) to Maximalize performance issue.

npm install lodash.debounce

Then let's adjust our App.js to look like this:

import React, { useState, useEffect } from "react";
import DataTable from "react-data-table-component";
import debounce from "lodash.debounce";

// Dummy local dataset
const localData = [
  {
    NO_RESI: "PLMAA16157522113",
    RECEIVER_NAME: "John Doe",
    RECEIVER_DIVISION: "IT",
    CREATED_DATE: "2025-04-11",
    STATUS_NAME: "Complete",
    STATUS: "002",
  },
  {
    NO_RESI: "PLMAA16157522112",
    RECEIVER_NAME: "Jane Doe",
    RECEIVER_DIVISION: "Finance",
    CREATED_DATE: "2025-04-10",
    STATUS_NAME: "On Progress",
    STATUS: "001",
  },
  // Add more dummy items here
];

const statusOptions = [
  { key: "001", status: "On Progress" },
  { key: "002", status: "Complete" },
];

const columns = [
  { name: "No Resi", selector: (row) => row.NO_RESI, sortable: true },
  { name: "Receiver", selector: (row) => row.RECEIVER_NAME, sortable: true },
  { name: "Receiver Division", selector: (row) => row.RECEIVER_DIVISION, sortable: true },
  { name: "Created Date", selector: (row) => row.CREATED_DATE, sortable: true },
  { name: "Status", selector: (row) => row.STATUS_NAME, sortable: true },
  {
    name: "Action",
    cell: (row) => (
      
        Detail
      
    ),
  },
];

const customStyles = {
  headCells: {
    style: {
      backgroundColor: "#919492",
      color: "#333",
      fontWeight: "bold",
      fontSize: "14px",
    },
  },
};

export default function App() {
  const [data, setData] = useState([]);
  const [search, setSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState("");
  const [loading, setLoading] = useState(false);

  const [totalRows, setTotalRows] = useState(0);
  const [perPage, setPerPage] = useState(10);
  const [currentPage, setCurrentPage] = useState(1);

  const filterLocalData = (page, size, searchText, statusKey) => {
    setLoading(true);

    let filtered = [...localData];

    if (searchText) {
      filtered = filtered.filter(
        (item) =>
          item.NO_RESI.toLowerCase().includes(searchText.toLowerCase()) ||
          item.RECEIVER_NAME.toLowerCase().includes(searchText.toLowerCase())
      );
    }

    if (statusKey) {
      filtered = filtered.filter((item) => item.STATUS === statusKey);
    }

    const start = (page - 1) * size;
    const paginated = filtered.slice(start, start + size);

    setData(paginated);
    setTotalRows(filtered.length);
    setLoading(false);
  };

  useEffect(() => {
    filterLocalData(currentPage, perPage, search, statusFilter);
  }, [search, statusFilter, perPage, currentPage]);

  const handlePageChange = (page) => {
    setCurrentPage(page);
  };

  const handlePerRowsChange = (newPerPage, page) => {
    setPerPage(newPerPage);
    setCurrentPage(page);
  };

  const debouncedSearch = debounce((val) => {
    setSearch(val);
  }, 500);

  return (
    
      
         setStatusFilter(e.target.value)}
        >
          All Status
          {statusOptions.map((opt) => (
            
              {opt.status}
            
          ))}
        

         debouncedSearch(e.target.value)}
        />
      

      
    
  );
}

Our react project will look like this:

Demo App