An easy way to create a customize dynamic table in react js
Abdul Basit

Abdul Basit @abdulbasit313

About: MERN Stack Developer at Orange Fox Labs

Location:
Karachi, Pakistan
Joined:
Mar 10, 2019

An easy way to create a customize dynamic table in react js

Publish Date: Mar 23 '19
174 78

In this article I will try to teach how to create a dynamic table in react.
Ya I know its quite simple, but this tutorial is for beginners and a beginner should know how to get this kind of stuff done.

I am assuming you know how to create a project and how javascript classes work. If you dont't, read this article first.

Lets begin
We have data in the form of array of objects just like APIs. You can use API too.

Lets create a simple component and store the data in the state.



import React, { Component } from 'react'

class Table extends Component {
   constructor(props) {
      super(props) //since we are extending class Table so we have to use super in order to override Component class constructor
      this.state = { //state is by default an object
         students: [
            { id: 1, name: 'Wasif', age: 21, email: 'wasif@email.com' },
            { id: 2, name: 'Ali', age: 19, email: 'ali@email.com' },
            { id: 3, name: 'Saad', age: 16, email: 'saad@email.com' },
            { id: 4, name: 'Asad', age: 25, email: 'asad@email.com' }
         ]
      }
   }

   render() { //Whenever our class runs, render method will be called automatically, it may have already defined in the constructor behind the scene.
      return (
         <div>
            <h1>React Dynamic Table</h1>
         </div>
      )
   }
}

export default Table //exporting a component make it reusable and this is the beauty of react


Enter fullscreen mode Exit fullscreen mode

We have 4 students with id, name, age and email address. Since our table will be dynamic so it doesn't matter if we have 4 or 100 students.

For Table Data

Now we want to print out students data in the Dom. We often use map function in react to itearate over array.
Lets write a separate function for table data and calling it in our render method. This approach will make our code cleaner and easier to read.



   renderTableData() {
      return this.state.students.map((student, index) => {
         const { id, name, age, email } = student //destructuring
         return (
            <tr key={id}>
               <td>{id}</td>
               <td>{name}</td>
               <td>{age}</td>
               <td>{email}</td>
            </tr>
         )
      })
   }

   render() {
      return (
         <div>
            <h1 id='title'>React Dynamic Table</h1>
            <table id='students'>
               <tbody>
                  {this.renderTableData()}
               </tbody>
            </table>
         </div>
      )
   }


Enter fullscreen mode Exit fullscreen mode

You may have noticed our renderTableData method only returns tr not the tr inside table. Since tr alone can not be a child of div so we have to wrap tr inside table and tbody in our render method.

table header

We are done with table data, a table should have a header too. Lets work on header.

For Table Header

Now we will write another method for table header.



   renderTableHeader() {
      let header = Object.keys(this.state.students[0])
      return header.map((key, index) => {
         return <th key={index}>{key.toUpperCase()}</th>
      })
   }

   render() {
      return (
         <div>
            <h1 id='title'>React Dynamic Table</h1>
            <table id='students'>
               <tbody>
                  <tr>{this.renderTableHeader()}</tr>
                  {this.renderTableData()}
               </tbody>
            </table>
         </div>
      )
   }


Enter fullscreen mode Exit fullscreen mode

Object.Keys gives us all the keys of students in the form of array and we stored it in a variable header. So we can iterate the header (array) using map method.
You may think why we don't use forEach, it does the same. The reason is when we want to return something as result we use map method, while forEach doesn't return anything, it just iterates over array's elements.

Styling

Lets add little bit styling in our table to make it look good



#title {
  text-align: center;
  font-family: arial, sans-serif;
}

#students {
  text-align: center;
  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  border-collapse: collapse;
  border: 3px solid #ddd;
  width: 100%;
}

#students td, #students th {
  border: 1px solid #ddd;
  padding: 8px;
}

#students tr:nth-child(even){background-color: #f2f2f2;}

#students tr:hover {background-color: #ddd;}

#students th {
  padding-top: 12px;
  padding-bottom: 12px;
  text-align: center;
  background-color: #4CAF50;
  color: white;
}


Enter fullscreen mode Exit fullscreen mode

table header

That's all, we are done with our basic table. In next article we will add some features in table, like sorting, adding and removing data. Here is the codepen link of the project.

Here you can read How To Create An Editable Text Field In Table Using ReactJS.

Comments 78 total

  • PharWana
    PharWanaMar 24, 2019

    brother, I need help regarding the quilljs? can you help me out?

    • Abdul Basit
      Abdul BasitMar 24, 2019

      Sorry, I never worked with quill. so no idea... if you want to know something related react I am here.

  • guico33
    guico33Mar 24, 2019
    key={Math.random()}
    

    The key is supposed to be consistent between renders, random generated is a very bad solution.
    Better use the array index if you don't have an unique identifier.

    • Abdul Basit
      Abdul BasitMar 24, 2019

      hmmm... nice catch. fixed

      • navas
        navas May 30, 2019

        hey man i have doubt in this how do i contact you?

  • Esin G
    Esin GJul 10, 2019

    Easy to follow! it helped me a lot. thanks!

  • akash thoriya
    akash thoriyaAug 17, 2019

    How can I add buttons to each row [For example Buttons could be View, Edit, Delete ]

  • fazzysyed
    fazzysyedOct 12, 2019

    how to add search and sorting in the table

    • Abdul Basit
      Abdul BasitOct 12, 2019

      You can use ant design for that. By the way I have plan to update this article in couple of days.

    • saltan-1
      saltan-1Jan 20, 2021

      How can I reach you regarding app development. Thanks

    • De_Codr
      De_CodrFeb 21, 2021

      u can go with MUI Data Tables they are awesome

  • Ayesha
    AyeshaOct 13, 2019

    Hi,

    Thanks for the Totorial, well explained!
    Where Can I find the other features "like sorting, adding and removing data" you mentioned above.
    Can I get the link of that Tutorial.
    Thanks

  • Micah Bala
    Micah BalaOct 21, 2019

    Thanks Abdul Basit for this tutorial, it helped me out, I have spend over 3 hours trying to render data from json on a table correctly. Thanks again.

  • Bharathkumar
    BharathkumarNov 15, 2019

    Suppose we want structure like "jsfiddle.net/cyril123/3n8xv3hL/" , how implement complex data with rowspan in react. Searched material-table but no luck it doesn't support complex data(material-table.com/).

  • Mạnh Đạt
    Mạnh ĐạtDec 13, 2019

    Thanks for the tutorial. I'm a react beginner.

    My question is, what if the number of column is unknown too?

    Thanks again

    • Abdul Basit
      Abdul BasitDec 14, 2019

      Here you go... you just need to change renderTableData function with below code. Let me know if it helps...

         renderTableData() {
            return this.state.students.map((student, index) => {
               let col = Object.keys(student)
               return (
                  <tr key={student.id}>
                     {col.map((val, index) => {
                        return <td key={index}>{student[col[index]]}</td>
                     })}
                  </tr>
               )
            })
         }
      
  • Stephanie
    StephanieDec 30, 2019

    So no follow up? : )

  • Alex Avelino Campos
    Alex Avelino CamposJan 9, 2020

    please, how can i just show specific columns, for example in the exercise I just want to see the Name and the Age

  • Ahmed Soliman
    Ahmed SolimanJan 21, 2020

    Hi Abdul Basit, this is very helpful to me. Thank you!

    How can I add rows to table dynamically? For example, if I create a table for a customer that have unknown number phone devices. So if a customer have 2 phone devices, we should have 2 rows, and if 3 phone devices, we should have 3 rows, etc.

    Would you be able to show us how to add rows to a table?

    Thanks
    Ahmed

  • Hendra Widjaja
    Hendra WidjajaJan 31, 2020

    You used too many ids. Be careful

  • blup00
    blup00Feb 11, 2020

    Thank you, great code, easy to follow!!

  • bishwobhandari
    bishwobhandariApr 11, 2020

    if i need to create a empty table of 10 rows where user can input data as form and submit the whole table to mobx store. how do i do it?

  • Swaminathan.V.B
    Swaminathan.V.BMay 6, 2020

    Hi Abdul, Thanks for the tutorial appreciated your work..I am having an issue to be resolved let me know how will you destruct and array of objects which are having key values with space in between for example

    const {Stock symbol,Stock name,No of share,Buy price,Current price,Profit Loss}= a;
    its throwing error like identified expected
    the example u have used all are single words for key like id,name,age,email...
    also explain for two words like first name?

    • Abdul Basit
      Abdul BasitMay 6, 2020
      let student = {
        "roll no" : 654321,
        "first name" : "John" 
        } 
      
      const {"roll no":  id,  "first name": name} = student
      
      console.log(id, name)
      

      Let me know if it helps...

  • ahmed houari
    ahmed houariMay 15, 2020

    He Abdul Basit,thanks for the very helpfull tutorial .How can i map a simple array[0,1....,8] in a table(3X3).

    • Abdul Basit
      Abdul BasitMay 16, 2020

      You need to write conditions inside your method...

      • ahmed houari
        ahmed houariMay 19, 2020

        thanks Abdul Basit.
        so i need two for loops as usual in js

  • Naeem-source
    Naeem-sourceMay 20, 2020

    Sir you done very well . THANKS U SO MUCH . i have a question , i want to call a component on the base of the column data as props for this component by clicking on a col.

    • Abdul Basit
      Abdul BasitMay 20, 2020

      Sorry, I didn't understand what do you want to ask. Do you want to toggle data or what?

  • Kartik Narang
    Kartik NarangMay 21, 2020

    can you please share an api implementation of this using axios.

  • MeiSaM Valizadeh
    MeiSaM ValizadehJun 27, 2020

    hello please help me for this error

    import React, { useState } from "react";

    import "./AddUser.css";
    import {
    validate,
    validatorRequire,
    validatorNumber,
    } from "../../shared/util/validator";
    import { Link } from "react-router-dom";
    import * as userService from "./service";

    const AddUser = () => {
    const [formState, setFormaState] = useState({
    errors: [],
    users: [],
    });
    // class addUser extends Component {
    // componentDidMount() {
    // userService
    // .getUsers()
    // .then((response) => this.setFormaState({ users: response.data }));
    // }
    // }
    // componentDidMount() {

    // }
    const addUserSubmitHandler = (event) => {
    event.preventDefault();
    const errors = validateForm();

    if (errors.length) {
      alert("gikhare sag");
      setFormaState({ ...formState, errors });
      return;
    }
    userService.addUser(formState.user);
    setFormaState({ errors: [], users: userService.getUsers() });
    

    };

    const validators = {
    code: [validatorRequire(), validatorNumber()],
    fname: [validatorRequire()],
    lname: [validatorRequire()],
    phone: [validatorRequire(), validatorNumber()],
    fee: [validatorRequire(), validatorNumber()],
    };

    const farsiNames = {
    code: "کد",
    fname: "نام",
    lname: "نام خانوادگی",
    phone: "شماره تماس",
    fee: "دستمزد",
    };

    const changeHandler = (e) => {
    const user = {};
    const name = e.target.name;
    const value = e.target.value;
    user[name] = value;
    const errors = validate(value, validators[name], farsiNames[name]);
    setFormaState({
    ...formState,
    user: { ...formState.user, ...user },
    errors,
    });
    };
    const validateForm = () => {
    let errors = [];
    const fields = Object.keys(farsiNames);
    for (let field of fields) {
    const fieldErrors = validate(
    formState.user ? formState.user[field] : undefined,
    validators[field],
    farsiNames[field]
    );
    errors = errors.concat(fieldErrors);
    }

    return errors;
    

    };

    return (


    {formState.errors.map((error, index) => (

    {error}

    ))}

    element="input"
    type="text"
    id="code"
    name="code"
    className="code form-control m-2 col-md-1 d-block"
    placeholder="کد"
    onChange={changeHandler}
    />
        <input
          element="input"
          type="text"
          id="fname"
          name="fname"
          className="fname form-control m-2 col-md-2 d-block"
          placeholder="نام"
          onChange={changeHandler}
        />
        <input
          element="input"
          type="text"
          id="lname"
          name="lname"
          className="lname form-control m-2 col-md-2 "
          placeholder="نام خانوادگی"
          onChange={changeHandler}
        />
        <input
          element="input"
          type="text"
          id="phone"
          name="phone"
          className="phone form-control m-2 col-md-3"
          placeholder="شماره تماس"
          onChange={changeHandler}
        />
        <input
          element="input"
          type="text"
          id="fee"
          name="fee"
          className="fee form-control col-md-3 m-2 p-3"
          placeholder="دستمزد"
          validators={[validatorRequire]}
          onChange={changeHandler}
        />
      </div>
    
      <button className="btn btn-success mx-auto d-block mt-5">
        اضافه کردن
      </button>
    
      <div className="container mt-5">
        <table className="table table-striped">
          <thead>
            <tr>
              <th scope="col">ردیف</th>
              <th scope="col">{farsiNames.code}</th>
              <th scope="col">{farsiNames.fname}</th>
              <th scope="col">{farsiNames.lname}</th>
              <th scope="col">{farsiNames.phone}</th>
              <th scope="col">{farsiNames.fee}</th>
            </tr>
          </thead>
    
          <tbody>
            {formState.users.map((user, index) => {
              return (
                <tr key={index}>
                  <th scope="row">{index + 1}</th>
                  <td>{user.code}</td>
                  <td>{user.fname}</td>
                  <td>{user.lname}</td>
                  <td>{user.phone}</td>
                  <td>{user.fee}</td>
                  <td>
                    <Link to={"/userfee/" + user.code}>
                      <span role="button" className="btn btn-primary btn-sm">
                        Edit
                      </span>
                    </Link>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </form>
    

    );
    };
    export default AddUser;

    error = react-dom.development.js:11102 Uncaught TypeError: formState.users.map is not a function
    at AddUser (AddUser.js:157)

    • Abdul Basit
      Abdul BasitJun 27, 2020

      Please ask this question on stackoverflow

  • shubham
    shubhamJul 20, 2020

    how to create a table like

    | Name | 1/1/2020 | 2/1/2020 | 3/1/2020 | 4/1/2020 | ........... (can be any number of dates)header

    | Raj | RajData | RajData | RajData | RajData | ............(data as per date for this name)body

    | . | X Data | X Data | X Data | X Data | ............(data as per date for this name)body

    .
    .

    names are dynamic too so please help me to solve this type of table structure in reactjs
    please help i have no clue for this kind of table as i am beginner

    • De_Codr
      De_CodrFeb 21, 2021

      u can go with MUI Data Tables they are easy to implement and more flexible to handle bulk data

  • phykurox
    phykuroxJul 28, 2020

    How do I renderTableData without refreshing whenever there's new data added to the state?

    • Abdul Basit
      Abdul BasitJul 30, 2020

      How you are adding new data? you just need to use spread operator if you are adding data locally. like [...oldState, newObj]

  • Aashiq Ahmed M
    Aashiq Ahmed MSep 25, 2020

    What if we want to render row from the data from the input field?

    • Abdul Basit
      Abdul BasitSep 25, 2020

      For that we will use another function called addData that will be called on clicking submit button, and we will add input data to our object using spread operator.

      • Aashiq Ahmed M
        Aashiq Ahmed MSep 25, 2020

        Ya it's a task given by my manager, finished it.i used a form with input fields and on submit I got the value by document.getelementbyid and pushed into the state object and rendered it as a seperate row and also added a delete functionality by filter out by the id prop.Btw great article!

        • Abdul Basit
          Abdul BasitSep 25, 2020

          Why did you use document.getElementById? In react we use e.target.value

          • Aashiq Ahmed M
            Aashiq Ahmed MSep 26, 2020

            Ya its cool,but i had more input fields in the form and I struggled to manage them,can you come up with a solution, [e,target.name]?

  • Aashiq Ahmed M
    Aashiq Ahmed MSep 29, 2020

    Hey im glad to start the discussion once again, I want to edit the row field may be by one time click on the row or having a separate button ,Can you explain to make it happen.

    • Abdul Basit
      Abdul BasitSep 29, 2020

      It depends on your approach. How do you want to edit? Do you have input fields for edit row data? I mean the same input fields which will be used to add and edit data, and the second approach is to convert the same row's td into input field

  • Harishchandra
    Harishchandra Oct 11, 2020

    After looking at your code it looks easy to me now 😀, I am trying to create table too, but I don't have table data, what I have is row no and column no and based on them I am tring to generate empty table for input, the problem which I am facing is creating header, do you have any suggestions for that ??, I really need some help

    • Abdul Basit
      Abdul BasitOct 11, 2020

      You mean let's say you want to generate 3×4 table?
      I am not really sure but you can store rows and columns numbers into variable and based on that generate the table.

      • Harishchandra
        Harishchandra Oct 11, 2020

        Yes, I am able to generate rows, but facing issue with creation of headers and then storing tables value in to variable in form of list of dictionary,
        Below is the part which is I am trying to build.
        codesandbox.io/s/issue-with-header...

  • Ali
    AliNov 2, 2020

    Very helpful article.

    But I want to fetch data from an API instead of this Array of object, can you tell me how?

  • FaizanMustafa
    FaizanMustafaNov 12, 2020

    Thanks ton. This post is really helpful for me.

  • SHANTANU SINGH
    SHANTANU SINGHDec 12, 2020

    if i just show Id, name only and when this datatable made nd in that if i click 2 nd no.
    of id then it goes to next page nd show full data??????

  • Femi Akinyemi
    Femi AkinyemiJan 4, 2021

    Nice Post But how do someone Put this type of Object in a Table ? {
    Australia: 1
    Burma: 2
    Canada: 3
    China: 1
    Cyprus: 1
    Egypt: 3
    France: 2
    Greece: 1
    Iran (Persia): 1
    Isle of Man: 1
    Japan: 1
    Norway: 1
    Russia: 4
    Singapore: 1
    Somalia: 1
    Thailand: 4
    Turkey: 2
    United Arab Emirates: 1
    United Kingdom: 8
    United States: 28}

    • Femi Akinyemi
      Femi AkinyemiJan 4, 2021

      Can someone please help me with this

    • Abdul Basit
      Abdul BasitJan 4, 2021

      You can do two things.

      1. Write the logic that changes this object into array or array of objects.
      2. If you have hard coded data then write it in this way countries : [ { country : 'US', id: 1, } ] Something like this
      • Femi Akinyemi
        Femi AkinyemiJan 4, 2021

        I think I will go with the first option. But will I be able to add the unique name and ID then

        • Abdul Basit
          Abdul BasitJan 4, 2021

          Yes you can further spread the object or array. Read about spread operator

    • Shahir Hussaini
      Shahir HussainiMar 22, 2021

      Object.keys(yourObject).map(obj => (


      {obj}
      {yourObject[obj]}

      ))

      use this method it will solve your problem.

  • Dirask-React
    Dirask-ReactFeb 17, 2021

    Hello 👋
    Thanks for sharing! 👍
    Recently I created a solution for dynamic table using functional components, so if you are interested you can go and check it. 😊
    dev.to/dirask/react-how-to-create-...

  • Parasbuda
    ParasbudaApr 18, 2021

    Can u give some example for implementing the dynamic table for multiple tables

  • Salimeh1364
    Salimeh1364Jun 26, 2021

    hi abdul ,
    in advance thanks for your clear code, i have a question
    i have one array that include fore example 10 field that each field has many information , i want to show each field in one table ,it means if i have 10 field in array show in 10 table saparately . thanks alot

  • HakimAsa
    HakimAsaAug 21, 2021

    nice article. However, your renderTableCell method should be dynamic as well, similar to what you've done with header.
    the inner return statement should be like what you see in the screenshot

  • Rahul More
    Rahul MoreOct 4, 2021

    How can I add CRUD BTns in each row.
    Also how can I status coloum with proper colours, like for active green and inactive red

  • kerenren
    kerenrenNov 1, 2021

    with

    element, it's not possible to add border radius and box shadow etc.

    any solution to achive this?
Add comment