How to Make a Table in React using Hooks with Multiple Features

Share your love

We all know how important tables are and we all have made them with different UIs in HTML, CSS, and JS. But today, we will be making the same table in React without using any other library or npm packages for any operation that our table will perform.

Let’s begin…


We have made dummy data for this project consisting of 10 objects with 6 key and value pairs as shown and named the file data.js.

Before we start the development, let’s see what the final result will look like.

We will not discuss the styling part of the app for that visit my Github repository 

Creating our React App

It’s easy to create a React App – go to the working directory in any IDE and enter the following command in the terminal:

npx create-react-app table-app-in-react

If you are unsure how to properly set up a create-react-app project you can refer to the official guide here at create-react-app-dev.‌‌

After the setup, run npm start in the same terminal to start the localhost:3000 where our React app will be hosted. We can also see all our changes there.

Working on the UI part of the app

For starters, let’s create a table with all the headings as per the dummy JSON data’s keys and print its values dynamically using the map() function.

In the above code, we can see two buttons with onClick event handlers. They will be responsible for editing and deleting rows respectively.

table in React
UI Table

Using the useState hook for defining and managing states 

We have made different states for each operation that the table will perform.

Also, readuseState Hook in React JS

Making the Form Component for adding a New Row 

UI part of the Form Component

We will be defining another useState hook here because we need to use the value attribute and onChange event handler to store the entered data.

const [newData, setNewData] = useState({
  fullName: "",
  userName: "",
  address: "",
  phoneNumber: "",
  email: "",
  website: "",
  companyName: "",

Our table consists of six columns, so we also need a six-columns here and a button that will trigger the add function by adding a new row with the details filled in the input.

The new row thus formed will be added at the very end of the table.

<h1 className="mx-3 mt-4">Add a contact</h1>
<Form tableData={tableData} setTableData={setTableData} />

 We will get something like this – 

Adding the details in the table from the Form Component 

Working on Other Functionalities

Delete Functionality

For activating the delete button of the table, we have to add an onClick event which will trigger the Delete() function. 

<button className="btn btn-danger" onClick={() => Delete(}>
  <i className="fa-solid fa-trash"></i>
const Delete = (del) => {
  const delData = tableData.filter((tbd) => {
    return del !==;

const Edit = (data) => {
  // for opening the editable row

Edit Functionality

We have to add an onClick event which will trigger the Edit()  function. 

<button className="btn btn-dark me-3" onClick={() => Edit(data)}>
  <i className="fa-solid fa-pen-to-square"></i>

Everything we have covered so far was super easy, but the hard part is about to begin.

We will be making a new table for editing the data and sending it back to the initial table for displaying it.

We will divide the UI of the App into two components, and pass the states defined at the top as props from each of them.

We will be using the toggle state for this which we have already defined above for targeting the ids of individual rows, and the ternary operator to toggle between the two components.

Working on the UI of the EditRow Component

We already have the value attributes and onChange in the above code for 

  1. Displaying the initial values of each column of the row triggered due to the Edit button.
  2. Updating and saving the values in the editData state.
  3. Sending this updated state back to the ReadOnly Component for displaying 

We have also placed an onClick event handler to trigger a set of different functions related to editing – Save and Cancel that performs the operations as their name. 

Saving the updated Row

So what’s going on here, let me explain.

We will filter the updated state to check and delete any other copies available of it, and with the help of sorting save the updated state at the same position as it was before updating the row.

If we want to cancel the edit, we can just click on the Cancel button provided which will trigger the Cancel functionality.

  const Cancel = () => {

Working on Sorting the table

There is a method in javascript through which we can easily sort things out in their increasing and decreasing order.

As we have to deal with both numbers and strings, we will use the compare function in sort to compare between numbers to sort them as well.

The initial value of the state used for sorting is ascending (“asc”) which will then be converted into descending order as shown above in the code.

The sorting will take place only when we click on the headings of each column. 

Working on Pagination for the table

For making the Pagination Component, there are some pre-defined values needed for specifying the index number of the first and last post for dividing the tableData accordingly.

We want the app to increase and decrease the page numbers automatically depending upon the data and the values like postPerPage we set in this case there are 10 posts and we have set the postPerPage to 4, so we will receive only 3 pages.


For a detailed explanation of the Pagination Component, click here.

Filter Component

We have come to the last section of our app, the filtration section. We will be filtering the table according to the username but you can use the same process to choose any other value or any number of values.

The UI part of the filter Component is very simple and consists of only one input field with a value attribute and an onChange event handler.

Now let’s understand how will the filtration take place. We will use the filter function before the map function with currentData. We did this because we want to access the data fetched dynamically before it even prints as UI of the app.

We have already defined a state specifically for this – search state. Now understand the following set of code

If the search state is empty, we will receive the data in the JSON format and it will be printed using the map method.

But if it contains a value, say username, then the row with that username will only be printed.

And now we can do any operation on that row after finding it like editing and deleting.


We have seen how to make a table in React which can perform operations like 

  1. Adding a New Row
  2. Deleting a Row
  3. Editing a Row
  4. Sorting the table for both alphabets and numerical values just by clicking the table header
  5. Pagination
  6. Username Filteration

We made all of this with only hooks without the use of any npm package or external library for any specific operation.

Share your love