Read data from database and display into table in ReactJS

In this article, we will learn how to Read data from a database and display it into a table in ReactJS. Below is the procedure we will be following. We will follow different procedures for the backend and front end.

For the backend, we will use node.js and for the database, we will be using mongodb.

  • Create a MongoDB cluster
  • Store some data in MongoDB
  • Install required dependencies for node.js
  • Create the API

For the front end, we will use TailwindCSS and DaisyUI for the styled component.

  • Setup the environment
  • Fetch data from the database
  • Create table
  • Show data in the table

Create MongoDB cluster

  • Click on Build Databse

  • Give a username and password to the cluster

  • Set IP address

  • Now click on Browse Collection

  • Create database and collection name

Store some data in MongoDB

  • Insert data

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "username": "Antonette",
    "email": "Shanna@melissa.tv",
    "address": {
      "street": "Victor Plains",
      "suite": "Suite 879",
      "city": "Wisokyburgh",
      "zipcode": "90566-7771",
      "geo": {
        "lat": "-43.9509",
        "lng": "-34.4618"
      }
    },
    "phone": "010-692-6593 x09125",
    "website": "anastasia.net",
    "company": {
      "name": "Deckow-Crist",
      "catchPhrase": "Proactive didactic contingency",
      "bs": "synergize scalable supply-chains"
    }
  },
  {
    "id": 3,
    "name": "Clementine Bauch",
    "username": "Samantha",
    "email": "Nathan@yesenia.net",
    "address": {
      "street": "Douglas Extension",
      "suite": "Suite 847",
      "city": "McKenziehaven",
      "zipcode": "59590-4157",
      "geo": {
        "lat": "-68.6102",
        "lng": "-47.0653"
      }
    },
    "phone": "1-463-123-4447",
    "website": "ramiro.info",
    "company": {
      "name": "Romaguera-Jacobson",
      "catchPhrase": "Face to face bifurcated interface",
      "bs": "e-enable strategic applications"
    }
  },
  {
    "id": 4,
    "name": "Patricia Lebsack",
    "username": "Karianne",
    "email": "Julianne.OConner@kory.org",
    "address": {
      "street": "Hoeger Mall",
      "suite": "Apt. 692",
      "city": "South Elvis",
      "zipcode": "53919-4257",
      "geo": {
        "lat": "29.4572",
        "lng": "-164.2990"
      }
    },
    "phone": "493-170-9623 x156",
    "website": "kale.biz",
    "company": {
      "name": "Robel-Corkery",
      "catchPhrase": "Multi-tiered zero tolerance productivity",
      "bs": "transition cutting-edge web services"
    }
  },
  {
    "id": 5,
    "name": "Chelsey Dietrich",
    "username": "Kamren",
    "email": "Lucio_Hettinger@annie.ca",
    "address": {
      "street": "Skiles Walks",
      "suite": "Suite 351",
      "city": "Roscoeview",
      "zipcode": "33263",
      "geo": {
        "lat": "-31.8129",
        "lng": "62.5342"
      }
    },
    "phone": "(254)954-1289",
    "website": "demarco.info",
    "company": {
      "name": "Keebler LLC",
      "catchPhrase": "User-centric fault-tolerant solution",
      "bs": "revolutionize end-to-end systems"
    }
  },
  {
    "id": 6,
    "name": "Mrs. Dennis Schulist",
    "username": "Leopoldo_Corkery",
    "email": "Karley_Dach@jasper.info",
    "address": {
      "street": "Norberto Crossing",
      "suite": "Apt. 950",
      "city": "South Christy",
      "zipcode": "23505-1337",
      "geo": {
        "lat": "-71.4197",
        "lng": "71.7478"
      }
    },
    "phone": "1-477-935-8478 x6430",
    "website": "ola.org",
    "company": {
      "name": "Considine-Lockman",
      "catchPhrase": "Synchronised bottom-line interface",
      "bs": "e-enable innovative applications"
    }
  },
  {
    "id": 7,
    "name": "Kurtis Weissnat",
    "username": "Elwyn.Skiles",
    "email": "Telly.Hoeger@billy.biz",
    "address": {
      "street": "Rex Trail",
      "suite": "Suite 280",
      "city": "Howemouth",
      "zipcode": "58804-1099",
      "geo": {
        "lat": "24.8918",
        "lng": "21.8984"
      }
    },
    "phone": "210.067.6132",
    "website": "elvis.io",
    "company": {
      "name": "Johns Group",
      "catchPhrase": "Configurable multimedia task-force",
      "bs": "generate enterprise e-tailers"
    }
  },
  {
    "id": 8,
    "name": "Nicholas Runolfsdottir V",
    "username": "Maxime_Nienow",
    "email": "Sherwood@rosamond.me",
    "address": {
      "street": "Ellsworth Summit",
      "suite": "Suite 729",
      "city": "Aliyaview",
      "zipcode": "45169",
      "geo": {
        "lat": "-14.3990",
        "lng": "-120.7677"
      }
    },
    "phone": "586.493.6943 x140",
    "website": "jacynthe.com",
    "company": {
      "name": "Abernathy Group",
      "catchPhrase": "Implemented secondary concept",
      "bs": "e-enable extensible e-tailers"
    }
  },
  {
    "id": 9,
    "name": "Glenna Reichert",
    "username": "Delphine",
    "email": "Chaim_McDermott@dana.io",
    "address": {
      "street": "Dayna Park",
      "suite": "Suite 449",
      "city": "Bartholomebury",
      "zipcode": "76495-3109",
      "geo": {
        "lat": "24.6463",
        "lng": "-168.8889"
      }
    },
    "phone": "(775)976-6794 x41206",
    "website": "conrad.com",
    "company": {
      "name": "Yost and Sons",
      "catchPhrase": "Switchable contextually-based project",
      "bs": "aggregate real-time technologies"
    }
  },
  {
    "id": 10,
    "name": "Clementina DuBuque",
    "username": "Moriah.Stanton",
    "email": "Rey.Padberg@karina.biz",
    "address": {
      "street": "Kattie Turnpike",
      "suite": "Suite 198",
      "city": "Lebsackbury",
      "zipcode": "31428-2261",
      "geo": {
        "lat": "-38.2386",
        "lng": "57.2232"
      }
    },
    "phone": "024-648-3804",
    "website": "ambrose.net",
    "company": {
      "name": "Hoeger LLC",
      "catchPhrase": "Centralized empowering task-force",
      "bs": "target end-to-end models"
    }
  }
]

Install required dependencies for Node.js

  • Create a folder for the backend server

  • Open the command prompt and run npm init -y command. It will add the package.json file to the folder.
  • Run the below command to the same folder in the command prompt
npm i express mongodb cors

express will install the dependencies for express.js, mongodb will allow us to use the database on our server, and cors used for the cross-platform policy so that the server can connect to the front end without interruption.

  • Create a file named, index.js

  • Write the below code in index.js
const express = require('express');
const app = express();
const cors = require('cors')
const port = process.env.PORT || 5000;
app.use(cors())
app.use(express.json())

app.get('/', (req, res) => {
    res.send('Hello World!')
})

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})

Here, the port defines the server route, in which path the data will be rendered. As we can see it is in 5000. So if we run http://localhost:5000/ , we will be able to ‘Hello world.

  • Declare the MongoDB URI and MongoDB client.
const uri = "mongodb+srv://userInfoDB:<password>@cluster0.7wjys8r.mongodb.net/?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });

Note: in the place of <password> you have to put the password of the mongodb cluster.

  • Create a run function
async function run() {
    try {
        await client.connect()
    } finally {
    }
}

run().catch(console.dir);
const { MongoClient, ServerApiVersion } = require('mongodb');
const express = require('express');
const app = express();
const cors = require('cors')
const port = process.env.PORT || 5000;
app.use(cors())
app.use(express.json())






const uri = "mongodb+srv://userInfoDB:<password>@cluster0.7wjys8r.mongodb.net/?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });


async function run() {
    try {
        await client.connect()
    } finally {
    }
}
run().catch(console.dir);






app.get('/', (req, res) => {
    res.send('Hello World!')
})

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})

Inside the run function, we will create our API endpoint.

Create the API

  • Store all the data from the database in a variable
const useCollection = client.db('userInfo').collection('name');
  • Use the get method to read all the data from the database.
app.get('/users', async (req, res) => {
            const query = {}
            const result = await userCollection.find(query).toArray()
            res.send(result)
        })

The full code will look like the below one,

const { MongoClient, ServerApiVersion } = require('mongodb');
const express = require('express');
const app = express();
const cors = require('cors')
const port = process.env.PORT || 5000;
app.use(cors())
app.use(express.json())





// add your password here at the <password>
const uri = "mongodb+srv://userInfoDB:<password>@cluster0.7wjys8r.mongodb.net/?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });


async function run() {
    try {
        await client.connect()
        const userCollection = client.db('userInfo').collection('name');

        app.get('/users', async (req, res) => {
            const query = {}
            const result = await userCollection.find(query).toArray()
            res.send(result)
        })


    } finally {
    }
}
run().catch(console.dir);






app.get('/', (req, res) => {
    res.send('Hello World!')
})

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})

After running the server, if we run the localhost, we will get an array of users which is coming from the database.

Now we can fetch these data in the front-end.

Setup environment with TailwindCSS and DaisyUI (Front-end)

  • Create a folder named, components inside the src of  React Project.
  • Create a functional component inside the component folder.

 

import React from 'react';

const TableData = () => {
    return (
        <div>

        </div>
    );
};

export default TableData;

  • The component is returning a <div>  and anything written inside  <div>...<div> will be visible in the browser.
import React from 'react';

const TableData = () => {
    return (
        <div>
            <h1 className="text-4xl text-center my-10">
                Dynamic Data in Table
            </h1>
        </div>
    );
};

export default TableData;

Here, we have added a <h1> tag. After importing this component to App.js, the elements inside this tag will be visible.

  • Import this component into the App.js file
import TableData from "./components/TableData";
import React, { useState, useEffect } from "react";
import TableData from "./components/TableData";


const App = () => {

  return (
    <div >
      <TableData />
    </div>
  );
}

export default App

The browser is rendering this App component. Anything was written here (inside the  <div>...<div>), we will be able to see the preview.

Note: To know more about setup an environment with TailwindCSS, Read This Article.

Fetch data from the database

const [users, setUsers] = useState([]);
  useEffect(() => {
    fetch('http://localhost:5000/users')
      .then(res => res.json())
      .then(data => setUsers(data))
  }, []);

Here, we are fetching data from the backend API that we created, and storing them in the useState() hook. To know more details about fetching data from an API, Read This Article.

Show Dynamic Data in Table

  • Create a table with <table>, <thead>, <tbody>, <tr> and <th>
import React from 'react';

const TableData = () => {
   
    return (
        <div>
            <h1 className="text-4xl text-center my-10">
                Dynamic Data in Table
            </h1>

            <div>
                <div class="overflow-x-auto">
                    <table class="table w-full">
                        <thead>
                            <tr>
                                <th></th>
                                <th>Name</th>
                                <th>Job</th>
                                <th>Favorite Color</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <th>1</th>
                                <td>Cy Ganderton</td>
                                <td>Quality Control Specialist</td>
                                <td>Blue</td>
                            </tr>

                        </tbody>
                    </table>
                </div>
            </div>

        </div>
    );
};

export default TableData;

These are some static data. But to show dynamic data, we have to map through the array that we have declared and return the <tr> inside JSX.

  • map through the users array and return a <tr> with dynamic data inside of it.
<thead>
     <tr>
       <th>ID</th>
       <th>Name</th>
       
     </tr>
</thead>
<tbody>
   {
       userDetails.map(user =>
       <tr>
          <th>{user.id}</th>
          <td>{user.name}</td>
         
       </tr>
       )
   }

</tbody>

Note: with the help of JSX expression, {} we can write some JavaScript methods inside JSX and render dynamic data according to a condition.

import React, { useEffect, useState } from 'react';

const TableData = () => {
    const [users, setUsers] = useState([]);
    useEffect(() => {
        fetch('http://localhost:5000/users')
            .then(res => res.json())
            .then(data => setUsers(data))
    }, []);

    return (
        <div>
            <h1 className="text-4xl text-center my-10">
                Dynamic Data in Table
            </h1>

            <div>
                <div class="overflow-x-auto">
                    <table class="table w-full">
                        <thead>
                            <tr>
                                <th>ID</th>
                                <th>Name</th>
                               
                            </tr>
                        </thead>
                        <tbody>
                            {
                                users.map(user =>
                                    <tr>
                                        <th>{user.id}</th>
                                        <td>{user.name}</td>
                                       
                                    </tr>
                                )
                            }

                        </tbody>
                    </table>
                </div>
            </div>

        </div>
    );
};

export default TableData;

See the above code snippet, after mapping the Array inside of the JSX expression, each time of the loop it returns a result (object), which will produce a <tr> with each object. Hence we will be able to get an equal amount of <tr> , as object that the Array holds.

  • Import this component in App.js
import TableData from "./components/TableData";
import React, { useState, useEffect } from "react";
import TableData from "./components/TableData";



const App = () => {

  return (
    <div >
      {/* anything inside this div will be visible to the browser */}
      <TableData />
    </div>
  );
}

export default App

 

This is how we can read data from a database and show them in a table in ReactJS.