Topic: MDBDatatable not updating with React state
Bridget Melvin premium asked 2 years ago
Expected behavior
When the edit button is pressed within a table row, I edit "user permissions" and change the role from 'User' to 'Collaborator'. The table show reflect the updated user state. Console logs show react is properly updating the state per a complex change mechanism (modals, handlers, HOCs) and it reflects back properly in console logs within the parent component. But the table never updates this for the values. I am not including the higher order components with the change handler having console.logs show that the state is being properly updated and passed down to UsersTable.js
Actual behavior When the user with role 'User' (table column) has its permissions updated to reflect role = 'Collaborator', the table never reflects this change. That is, it stays the same.
Resources (screenshots, code snippets etc.)
UsersTable.js
export default function UsersTable({ company, editUser, openModal }) {
const [usersData, setUsersData] = useState(addCustomButtons(company.users.rows));
const [colData, setColData] = useState(company.users.columns);
const [tableData, setTableData] = useState({
columns: company.users.columns,
rows: usersData
})
console.log('UsersTable.js usersData', usersData)
useEffect(() => {
console.log('UsersTable useEffect')
setTableData(prevState => ({
...prevState,
rows: addCustomButtons(company.users.rows)
}))
}, [company])
console.log('UsersTable.js company', company)
console.log('tableData', tableData)
// console.log('Users', Users)
// console.log('usersData', usersData)
function addCustomButtons(users) {
const usersArr = [];
let idx = 0;
users.map((row) => {
if (company.userIds.includes(row.id)) {
usersArr.push({
...row,
index: idx,
email: (
<StyledLink
to='#'
onClick={(e) => {
window.location.href = `mailto:${row.emailraw}`;
e.preventDefault();
}}
>
{row.emailraw}
</StyledLink>
),
buttons: (
<>
<StyledButton
size='sm'
floating
className='message-btn'
onClick={() => console.log(`send a message to ${row.emailraw}`)}
>
<MDBIcon icon='envelope' />
</StyledButton>
<StyledButton
id={`edit-btn-${idx}`}
outline
size='sm'
floating
className='call-btn'
onClick={(event) => editUserHandler(event)}
>
<MDBIcon icon='ellipsis-h' />
</StyledButton>
<StyledTrash
id={`remove-btn-${idx}`}
bemkey={`remove-btn-${idx}`}
size='sm'
floating
className='remove-user-btn'
onClick={(event) => deleteRow(event)}
// onClick={(event) => printEvent(event)}
>
<MDBIcon icon="trash" />
</StyledTrash>
</>
),
});
idx = ++idx;
}
// console.log('usersArr', usersArr)
})
return usersArr;
}
const removeRow = (index) => {
const oldRows = [...usersData]
console.log('index', index, 'old rows', oldRows)
console.log(index)
const updatedRows = oldRows.filter((row) => row.index === index);
console.log('updated', updatedRows)
setUsersData([...updatedRows])
setTimeout(() => {
console.log('timer', usersData)
}, 3000)
}
const editUserHandler = (event) => {
const index = parseInt(buttonEventHandler(event))
const oldUser = usersData.filter(entry => entry.index === index)[0]
// console.log('selected user', index, oldUser)
openModal(oldUser);
}
function buttonEventHandler(event) {
let parentId = ''
// console.log('node name', event.target.nodeName)
if (event.target.nodeName !== 'BUTTON') {
// console.log('parent node', event.target.parentNode.attributes.id)
parentId = event.target.parentNode.attributes.id.value
} else {
// console.log('button node', event.target.attributes.id)
parentId = event.target.attributes.id.value
}
if (parentId !== '') {
parentId = parentId.substring(parentId.search('-btn-')).replace('-btn-', '')
// console.log('parentId', parentId)
}
return parentId
}
const deleteRow = (event) => {
if (usersData.length > 0) {
let updatedRows = [...usersData]
console.log('1st rowData', updatedRows)
const parentId = buttonEventHandler(event)
let indexToRemove = updatedRows.findIndex(x => parseInt(parentId) === x.index)
// console.log('remove (found, dictated)', indexToRemove, parentId)
if (indexToRemove > -1) {
updatedRows.splice(indexToRemove, 1)
var newRows = addCustomButtons(updatedRows)
console.log('new rows', newRows)
newRows = addCustomButtons(newRows);
setUsersData(newRows)
}
}
}
function Table({ users }) {
let tableData = {
columns: colData,
rows: usersData
}
// console.log('tableData', tableData)
useEffect(() => {
tableData = {
columns: colData,
rows: usersData
}
}, [usersData])
// console.log('tableData post useEffect', tableData)
return (
<StyledTable
hover
striped
data={tableData}
entriesOptions={[5, 10, 20]}
entries={10}
fixedHeader
maxHeight='460px'
/>
)
}
return (
<Wrapper>
<TableContainer>
<Table users={usersData} />
</TableContainer>
</Wrapper>
);
}
Before update
After update
repo repo url (within packages/company/src/components/table/UsersTable.js
Wojciech Staniszewski staff answered 2 years ago
This line:
tableData = {
columns: colData,
rows: usersData
}
will update your data, but it will not cause a rerender. That is why you have something like setTableData
. You should not update your state the way you did here.
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- ForumUser: Premium
- Premium support: Yes
- Technology: MDB React
- MDB Version: MDB5 4.1.0
- Device: Surface Laptop Studio
- Browser: Chrome
- OS: Windows 11
- Provided sample code: Yes
- Provided link: Yes