\n
View All Page:
\nimport React, { useEffect, useState } from 'react'\nimport {\n CButton,\n CCard,\n CCardBody,\n CCardHeader,\n CCol,\n CRow,\n CSpinner,\n CTable,\n CTableBody,\n CTableDataCell,\n CTableHead,\n CTableHeaderCell,\n CTableRow,\n} from '@coreui/react'\nimport CIcon from '@coreui/icons-react'\nimport { cilTrash, cilLockLocked } from '@coreui/icons'\n\nconst ViewAll = () => {\n const [usersData, setUsersData] = useState({})\n\n const [disabled, setDisabled] = useState(false)\n\n const handleLoadMembers = async () => {\n try {\n const _data = await fetch('http://localhost:4000/api/v1/member/list', {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Bearer ' + localStorage.getItem('token'),\n },\n })\n\n if (_data.status !== 200) {\n throw new Error()\n }\n\n const data = await _data.json()\n setUsersData(data.members)\n } catch (err) {\n console.error(err)\n }\n }\n\n const handleDelete = async (id) => {\n alert('clicked')\n try {\n const _data = await fetch('http://localhost:4000/api/v1/member/remove/' + id, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Bearer ' + localStorage.getItem('token'),\n },\n })\n window.location.reload()\n\n console.log(_data)\n } catch (err) {\n console.error(err)\n }\n }\n\n useEffect(() => {\n handleLoadMembers()\n }, [])\n\n return (\n <CRow>\n <CCol xs={12}>\n <CCard className="mb-4">\n <CCardHeader>\n <strong>All Members</strong>\n </CCardHeader>\n\n {usersData.length > 0 ? (\n <CCardBody>\n <p className="text-medium-emphasis small">Here the all members of your community.</p>\n <CTable hover bordered>\n <CTableHead color="dark">\n <CTableRow>\n <CTableHeaderCell scope="col">Member ID</CTableHeaderCell>\n <CTableHeaderCell scope="col">Name</CTableHeaderCell>\n <CTableHeaderCell scope="col">Email</CTableHeaderCell>\n <CTableHeaderCell scope="col">Actions</CTableHeaderCell>\n </CTableRow>\n </CTableHead>\n <CTableBody>\n {usersData.map((item, index) => {\n return (\n <CTableRow key={index}>\n <CTableHeaderCell scope="row">M_{item.index}</CTableHeaderCell>\n <CTableDataCell>{item.name}</CTableDataCell>\n <CTableDataCell>{item.email}</CTableDataCell>\n <CTableDataCell class="d-flex justify-content-evenly">\n <CButton\n color="danger"\n size="sm"\n disabled={disabled}\n onClick={() => handleDelete(item._id)}\n >\n {disabled ? (\n <CSpinner\n component="span"\n className="me-2"\n size="sm"\n aria-hidden="true"\n />\n ) : (\n <CIcon icon={cilTrash} className="me-2" />\n )}\n Delete\n </CButton>\n <CButton\n color="warning"\n size="sm"\n disabled={disabled}\n onClick={() => handleDelete(item._id)}\n >\n {disabled ? (\n <CSpinner\n component="span"\n className="me-2"\n size="sm"\n aria-hidden="true"\n />\n ) : (\n <CIcon icon={cilLockLocked} className="me-2" />\n )}\n Disable\n </CButton>\n </CTableDataCell>\n </CTableRow>\n )\n })}\n </CTableBody>\n </CTable>\n </CCardBody>\n ) : (\n 'No data'\n )}\n </CCard>\n </CCol>\n </CRow>\n )\n}\n\nexport default ViewAll\n
\n","author":{"@type":"Person","name":"nipoo"},"upvoteCount":0,"answerCount":2,"acceptedAnswer":null}}Reputation: 174
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.
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 class="d-flex justify-content-evenly">
<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
Upvotes: 0
Views: 219
Reputation: 34
A better idea is to use react with redux for state management.
Steps to solve the problem:
Hope you could understand the steps. All the best!!!!
Upvotes: 1