Home > Enterprise >  How to update individually buttons icons got from a same component in React
How to update individually buttons icons got from a same component in React

Time:01-03

I have a View All page. The page has a table with user data with actions that can be performed. The button has two different icons. Spinner icon and a default icon. I want to change the icon of the button until the task executes.

Ex: Showing spinner icon until M_1's disabling/deleting process works and showing back the lock/trash icon.

I know how to update one button icon by putting useState. When 1 row has 2 buttons that mean 2 useStates. So 2 rows mean 4 useStates. But that's not practical noh. I want to know how to do it the correct way.

Table with buttons: enter image description here

View All Page:

import React, { useEffect, useState } from 'react'
import {
  CButton,
  CCard,
  CCardBody,
  CCardHeader,
  CCol,
  CRow,
  CSpinner,
  CTable,
  CTableBody,
  CTableDataCell,
  CTableHead,
  CTableHeaderCell,
  CTableRow,
} from '@coreui/react'
import CIcon from '@coreui/icons-react'
import { cilTrash, cilLockLocked } from '@coreui/icons'

const ViewAll = () => {
  const [usersData, setUsersData] = useState({})

  const [disabled, setDisabled] = useState(false)

  const handleLoadMembers = async () => {
    try {
      const _data = await fetch('http://localhost:4000/api/v1/member/list', {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'Bearer '   localStorage.getItem('token'),
        },
      })

      if (_data.status !== 200) {
        throw new Error()
      }

      const data = await _data.json()
      setUsersData(data.members)
    } catch (err) {
      console.error(err)
    }
  }

  const handleDelete = async (id) => {
    alert('clicked')
    try {
      const _data = await fetch('http://localhost:4000/api/v1/member/remove/'   id, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'Bearer '   localStorage.getItem('token'),
        },
      })
      window.location.reload()

      console.log(_data)
    } catch (err) {
      console.error(err)
    }
  }

  useEffect(() => {
    handleLoadMembers()
  }, [])

  return (
    <CRow>
      <CCol xs={12}>
        <CCard className="mb-4">
          <CCardHeader>
            <strong>All Members</strong>
          </CCardHeader>

          {usersData.length > 0 ? (
            <CCardBody>
              <p className="text-medium-emphasis small">Here the all members of your community.</p>
              <CTable hover bordered>
                <CTableHead color="dark">
                  <CTableRow>
                    <CTableHeaderCell scope="col">Member ID</CTableHeaderCell>
                    <CTableHeaderCell scope="col">Name</CTableHeaderCell>
                    <CTableHeaderCell scope="col">Email</CTableHeaderCell>
                    <CTableHeaderCell scope="col">Actions</CTableHeaderCell>
                  </CTableRow>
                </CTableHead>
                <CTableBody>
                  {usersData.map((item, index) => {
                    return (
                      <CTableRow key={index}>
                        <CTableHeaderCell scope="row">M_{item.index}</CTableHeaderCell>
                        <CTableDataCell>{item.name}</CTableDataCell>
                        <CTableDataCell>{item.email}</CTableDataCell>
                        <CTableDataCell >
                          <CButton
                            color="danger"
                            size="sm"
                            disabled={disabled}
                            onClick={() => handleDelete(item._id)}
                          >
                            {disabled ? (
                              <CSpinner
                                component="span"
                                className="me-2"
                                size="sm"
                                aria-hidden="true"
                              />
                            ) : (
                              <CIcon icon={cilTrash} className="me-2" />
                            )}
                            Delete
                          </CButton>
                          <CButton
                            color="warning"
                            size="sm"
                            disabled={disabled}
                            onClick={() => handleDelete(item._id)}
                          >
                            {disabled ? (
                              <CSpinner
                                component="span"
                                className="me-2"
                                size="sm"
                                aria-hidden="true"
                              />
                            ) : (
                              <CIcon icon={cilLockLocked} className="me-2" />
                            )}
                            Disable
                          </CButton>
                        </CTableDataCell>
                      </CTableRow>
                    )
                  })}
                </CTableBody>
              </CTable>
            </CCardBody>
          ) : (
            'No data'
          )}
        </CCard>
      </CCol>
    </CRow>
  )
}

export default ViewAll

CodePudding user response:

A better idea is to use react with redux for state management.

Steps to solve the problem:

  1. Make 3 action types (request, success, failure).
  2. Integrate the API calls on the actions/sagas file.
  3. Whenever you delete a particular data from the table, the request action will dispatch to the store at that time you could set particular data/ item id and the loading flag to true in the request reducer type.
  4. Once the action dispatches the success at that time make sure to set the loading to false in success reducer type and similarly in failure.
  5. Get the id and loading value in props and display the actions whatever you want to show(spinner on deleting/disabling).

Hope you could understand the steps. All the best!!!!

CodePudding user response:

how about make CButton to components and hand over props false, true

  • Related