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

permissions as 'User'

After update

permissions as 'Collaborator' but table still shows 'User'

repo repo url (within packages/company/src/components/table/UsersTable.js



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.



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • 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