reactjsjsonreact-componentreact-tablereact-data-table-component

How to Display data of single json file in mulitple tables through repeating a single react component


I am a beginner in ReactJS. What I want is, I have a Component Datatable.js and I want to create three tables in that component by configuring data of a single JSON File and there should be only one component for three tables but the condition is the values in tables must come different-different in each table like- in first tables- Name, email, number; in the second table- email, city, number and in the third table- Name, Profession, number, city. I want to perform all that operation by repeating Datatable.js component three times in App.js so that three tables render, not by writing table element three times in Datatable.js.

So please tell me how to do that.

I have got the JSON values in the data state and I know it can be displayed through the map() method but the problem is how to send these JSON file values in each repeating component and how Datatable.js would get it so that values would appear differently in each table as I mentioned above?

data.json:

[
    {
      "person": {
        "name": "Viswas Jha",
        "avatar": "images/profile.jpg"
      },
      "city": "Mumbai",
      "email": "vishwasjha@gmail.com",
      "number": 123456,
      "profession": "UI Designer"
    },
    {
      "person": {
        "name": "Damini Pandit",
        "avatar": "images/profile.jpg"
      },
      "city": "Delhi",
      "email": "daminipandit@gmail.com",
      "number": 1345645,
      "profession": "Front-end Developer"
    },
    {
      "person": {
        "name": "Nihal Lingesh",
        "avatar": "images/profile.jpg"
      },
      "city": "Delhi",
      "email": "nihallingesh@gmail.com",
      "number": 12345689,
      "profession": "UX Designer"
    },
    {
      "person": {
        "name": "Akash Singh",
        "avatar": "images/profile.jpg"
      },
      "city": "Kolkata",
      "email": "akashsingh@gmail.com",
      "number": 1234566,
      "profession": "Backend Developer"
    }
    
  ]

App.js:

import Datatable from './Datatable';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import {useState, useEffect} from 'react';
import './App.css';

const fetchData = new Promise((myResolve, myReject) => {
    let req = new XMLHttpRequest();
    req.open('GET', "./data.json");
    req.onload = function() {
    if (req.status == 200) {
      return myResolve(req.response);
    } else {
      return myReject("File not Found");
    }
  };
  req.send();
});


function App() {
  
  const [data, setData] = useState([]);

  useEffect(() => {
    fetchData.then((jsonData) => setData(JSON.parse(jsonData)));
  }, []);

  return (
    <>
      <Datatable Data = {data} />;
      <Datatable Data= {data}/>;
      <Datatable Data= {data}/>;
    </>
  );
}

export default App;

Datatable.js:

import React from 'react';
import Grid from '@material-ui/core/Grid';


export default function Datatable({Data}) {

    
    return (
        <div className='main text-center '>
            <h1 className='head py-3'>Datatable</h1>
            <Grid container spacing={1} className='contain m-auto mt-5 ps-5 pb-4'>
                    <table className="table table-striped">
                        <thead>
                            <tr>
                            <th scope="col">Name</th>
                            <th scope="col">Email</th>
                            <th scope="col">Number</th>
                            </tr>
                        </thead>
                        <tbody> 
                        {
                            Data.map((elem, ind)=>{
                            return (
                                <tr key={ind}>
                                    
                                    <td className='d-flex justify-content-between align-items-center'>
                                    <img src={elem.person.avatar} alt="avatar"/>
                                    {elem.person.name}</td>
                                    <td>{elem.email}</td>
                                    <td>{elem.number}</td>
                                  
                                </tr>
                            )
                            })
                        }
                            
                        </tbody>
                    </table>   
            </Grid>
        </div>
        );

    }

Solution

  • Update your code with this.

    App.js

    import Datatable from './Datatable';
    import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
    import { useState, useEffect } from 'react';
    import './App.css';
    
    const fetchData = new Promise((myResolve, myReject) => {
        let req = new XMLHttpRequest();
        req.open('GET', "./data.json");
        req.onload = function () {
            if (req.status == 200) {
                return myResolve(req.response);
            } else {
                return myReject("File not Found");
            }
        };
        req.send();
    });
    
    
    function App() {
        const [sortReverse,setSortReverse] = useState(false)
        const [data, setData] = useState({
            tableOne: [],
            tableTwo: [],
            tableThree: [],
        });
    
        useEffect(() => {
            fetchData.then(function (jsonData) {
                const tableOne = jsonData?.map(
                    ({ person: { name }, email, number }) => ({
                        name,
                        email,
                        number,
                    })
                );
                const tableTwo = jsonData?.map(({ city, email, number }) => ({
                    city,
                    email,
                    number,
                }));
                const tableThree = jsonData?.map(
                    ({ person: { name }, email, number, city }) => ({
                        name,
                        email,
                        number,
                        city,
                    })
                );
                setData({
                    tableOne: tableOne,
                    tableTwo: tableTwo,
                    tableThree: tableThree,
                });
            });
        }, []);
    
     const handleSort = (e) => {
     const sortedArrTableOne = data?.tableOne?.sort((a, b) => {
       return sortReverse
         ? a[e.toLowerCase()]?.localeCompare(b[e.toLowerCase()])
         : b[e.toLowerCase()]?.localeCompare(a[e.toLowerCase()]);
     });
    
     const sortedArrTableTwo = data?.tableTwo?.sort((a, b) => {
       return sortReverse
         ? a[e.toLowerCase()]?.localeCompare(b[e.toLowerCase()])
         : b[e.toLowerCase()]?.localeCompare(a[e.toLowerCase()]);
     });
    
     const sortedArrTableThree = data?.tableThree?.sort((a, b) => {
       return sortReverse
         ? a[e.toLowerCase()]?.localeCompare(b[e.toLowerCase()])
         : b[e.toLowerCase()]?.localeCompare(a[e.toLowerCase()]);
     });
     setData((prevState) => ({
       ...prevState,
       tableOne: sortedArrTableOne,
       tableTwo: sortedArrTableTwo,
       tableThree: sortedArrTableThree,
     }));
     setSortReverse(!sortReverse)}
    
        const tableOneColumns = [
            { name: "Name", accessor: "name" },
            { name: "Email", accessor: "email" },
            { name: "Number", accessor: "number" },
        ];
    
        const tableTwoColumns = [
            { name: "Email", accessor: "email" },
            { name: "City", accessor: "city" },
            { name: "Number", accessor: "number" },
        ];
    
        const tableThreeColumns = [
            { name: "Name", accessor: "name" },
            { name: "Email", accessor: "email" },
            { name: "Number", accessor: "number" },
            { name: "City", accessor: "city" },
        ];
    
        return (
            <>
                <Datatable data={data?.tableOne} columns={tableOneColumns} handleSort={handleSort}/>
                <Datatable data={data?.tableTwo} columns={tableTwoColumns} handleSort={handleSort}/>
                <Datatable data={data?.tableThree} columns={tableThreeColumns} handleSort={handleSort}/>
            </>
        );
    }
    
    export default App;
    

    DataTable.js

    import React from "react";
    import Grid from "@material-ui/core/Grid";
    import { Box } from "@material-ui/core";
    
    export default function Datatable(props) {
      const { data = [], columns = [], handleSort } = props;
    
      return (
        <Box className="main text-center ">
          <h1 className="head py-3">Datatable</h1>
          <Grid container spacing={1} className="contain m-auto mt-5 ps-5 pb-4">
            <table className="table table-striped ">
              <thead>
                <tr>
                  {columns?.map((column, index) => (
                    <th key={index} scope="col" onClick={()=> handleSort(column?.name)}>
                      {column?.name}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {data.map((elem, ind) => {
                  return (
                    <tr key={ind}>
                      {columns?.map((column) => {
                        return (
                          <td className="d-flex justify-content-between align-items-center">
                            {elem?.[column.accessor]}
                          </td>
                        );
                      })}
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </Grid>
        </Box>
      );
    }
    

    Note: If you want to sort then click on heading Name or Email etc.