1

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>
        );

    }

1 Answers1

0

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.

  • 1
    Thank a lot for the response, yes I wanted this kind of output but there is something change that I don't want to repeat table element 2 times more in Datatable.js component as you did, I only want is to show three tables by return 3 Datatable.js component as I mentioned earlier in App.js code which you removed in your. So please tell me the solution of this. – Rahul Upadhyay Dec 04 '22 at 19:41
  • Hey, Buddy, I have Updated the code Please check it. – Naju Bhadarka Dec 05 '22 at 14:35
  • 1
    thanks a lot, you are genius everything is perfect but all values coming in a single column not separated into other columns any issue there?, and I also want to perform Sorting in columns like in the 1st table- sorting should be applicable only in 1st column, in 2nd table should be in last two columns and in the third table should be in 2nd and 4th column, so can you please also give me the solution of this? I, ll be highly obliged of you. – Rahul Upadhyay Dec 05 '22 at 17:44
  • I have Updated the code for Sorting. And Please read Note which is mentioned at last. Thanks. – Naju Bhadarka Dec 06 '22 at 05:48
  • 1
    thankyou so much for helping me a lot, I have learned many from you and have marked this as the answer. Would love to connect you again with some new one, again Thanks a lot! – Rahul Upadhyay Dec 06 '22 at 07:09
  • 1
    Yah!, I have been given upvotes. And you are not just leaner you are far more than it. – Rahul Upadhyay Dec 06 '22 at 11:02