0
votes

I'm trying to map some json elements to a Table (Customers.jsx using ) but can't see to figure out the correct way. How to insert my Fetch Method into Customers.jsx correctly? especially map renderBody part and the bodyData={/The JsonData/}

Fetch method

componentDidMount() {
    this.refershList();
}

async refershList() {
    const cookies = new Cookies();
    await fetch('https://xxxxxxxxxxxxxxxxx/Customers', {
        headers: { Authorization: `Bearer ${cookies.get('userToken')}` }
    })
        .then(response => response.json())
        .then(data => {
            this.setState({ deps: data });
        });
}

Customers.jsx

import React from 'react'

import Table from '../components/table/Table'


const customerTableHead = [
    '',
    'name',
    'email',
    'phone',
    'total orders',
    'total spend',
    'location'
]

const renderHead = (item, index) => <th key={index}>{item}</th>

const renderBody = (item, index) => (
    <tr key={index}>
        <td>{item.id}</td>
        <td>{item.name}</td>
        <td>{item.email}</td>
        <td>{item.phone}</td>
        <td>{item.total_orders}</td>
        <td>{item.total_spend}</td>
        <td>{item.location}</td>
    </tr>
)

const Customers = () => {
    return (
        <div>
            <h2 className="page-header">
                customers
            </h2>
            <div className="row">
                <div className="col-12">
                    <div className="card">
                        <div className="card__body">
                            <Table
                                limit='10'
                                headData={customerTableHead}
                                renderHead={(item, index) => renderHead(item, index)}
                                bodyData={/*The JsonData*/}
                                renderBody={(item, index) => renderBody(item, index)}
                            />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}

export default Customers

API JSON data

[
   {
      "id":1,
      "name":"Brittan Rois",
      "email":"[email protected]",
      "location":"Bator",
      "phone":"+62 745 807 7685",
      "total_spend":"$557248.44",
      "total_orders":24011
   },
   {
      "id":2,
      "name":"Matthew Junifer",
      "email":"[email protected]",
      "location":"Bromma",
      "phone":"+46 993 722 3008",
      "total_spend":"$599864.94",
      "total_orders":60195
   },
   {
      "id":3,
      "name":"Finlay Baylay",
      "email":"[email protected]",
      "location":"Atalaia",
      "phone":"+55 232 355 3569",
      "total_spend":"$171337.47",
      "total_orders":96328
   },
   {
      "id":4,
      "name":"Beryle Monelli",
      "email":"[email protected]",
      "location":"Martingança",
      "phone":"+351 734 876 8127",
      "total_spend":"$335862.78",
      "total_orders":78768
   }
]

Table.jsx

import React, {useState} from 'react'

import './table.css'

const Table = props => {

    const initDataShow = props.limit && props.bodyData ? props.bodyData.slice(0, Number(props.limit)) : props.bodyData

    const [dataShow, setDataShow] = useState(initDataShow)

    let pages = 1

    let range = []

    if (props.limit !== undefined) {
        let page = Math.floor(props.bodyData.length / Number(props.limit))
        pages = props.bodyData.length % Number(props.limit) === 0 ? page : page + 1
        range = [...Array(pages).keys()]
    }

    const [currPage, setCurrPage] = useState(0)

    const selectPage = page => {
        const start = Number(props.limit) * page
        const end = start + Number(props.limit)

        setDataShow(props.bodyData.slice(start, end))

        setCurrPage(page)
    }

    return (
        <div>
            <div className="table-wrapper">
                <table>
                    {
                        props.headData && props.renderHead ? (
                            <thead>
                                <tr>
                                    {
                                        props.headData.map((item, index) => props.renderHead(item, index))
                                    }
                                </tr>
                            </thead>
                        ) : null
                    }
                    {
                        props.bodyData && props.renderBody ? (
                            <tbody>
                                {
                                    dataShow.map((item, index) => props.renderBody(item, index))
                                }
                            </tbody>
                        ) : null
                    }
                </table>
            </div>
            {
                pages > 1 ? (
                    <div className="table__pagination">
                        {
                            range.map((item, index) => (
                                <div key={index} className={`table__pagination-item ${currPage === index ? 'active' : ''}`} onClick={() => selectPage(index)}>
                                    {item + 1}
                                </div>
                            ))
                        }
                    </div>
                ) : null
            }
        </div>
    )
}

export default Table

Table.css

    .table-wrapper {
    overflow-y: auto;
}

table {
    width: 100%;
    min-width: 400px;
    border-spacing: 0;
}

thead {
    background-color: var(--second-bg);
}

tr {
    text-align: left;
}

th,
td {
    text-transform: capitalize;
    padding: 15px 10px;
}

tbody > tr:hover {
    background-color: var(--main-color);
    color: var(--txt-white);
}

.table__pagination {
    display: flex;
    width: 100%;
    justify-content: flex-end;
    align-items: center;
    margin-top: 20px;
}

.table__pagination-item ~ .table__pagination-item {
    margin-left: 10px;
}

.table__pagination-item {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.table__pagination-item.active,
.table__pagination-item.active:hover {
    background-color: var(--main-color);
    color: var(--txt-white);
    font-weight: 600;
}

.table__pagination-item:hover {
    color: var(--txt-white);
    background-color: var(--second-color);
}
1

1 Answers

0
votes

To handle this case you can use the useEffect hook inside the component. This hook lets you execute a function when the component mounts and whenever any variable defined in its dependencies array changes. Like this:

const Customers = () => {
    //...

    const [deps, setDeps] = useState();

    refreshList() {
        const cookies = new Cookies();
        fetch('https://xxxxxxxxxxxxxxxxx/Customers', {
            headers: { Authorization: `Bearer ${cookies.get('userToken')}` }
        }).then(response => response.json()).
           then(data => {
                setDeps(data);
        });
    }

    //This effect will call refreshList() when the component is mounted
    useEffect(() => {
        refreshList();
    }, []); //The empty array tells that this will be executed only when the component mounts

    //...
}