alilland
alilland

Reputation: 2572

Material UI Table component is not playing nice with Redux

Versions
Material-UI: 0.18.0
React: 15.5.4
Redux: 3.6.0
Browser: Chrome -- Version 59.0.3071.115 (Official Build) (64-bit)

Problem
I am using redux for application wide state management instead of setState. When calling redux actions the checkbox doesn't register as checked, but it registers that it was clicked when I console.log the onRowSelection. If I remove the line calling my action, the checkboxes work just fine. For some reason, Material UI is blocked from updating when I call my redux action.

--Edit--
It appears that it's not the action that is causing the malfunction it's something about my reducer that material UI's Table doesn't like.
(added reducer snippet below)

Table Component

class AdminDeptAppAccess extends React.Component {

  _onRowSelection (selectedUsers, props) {
    console.log(selectedUsers)
    props.selectedUsersAction(filterUsers(selectedUsers, props.deptAppRoles))
  }

  render () {
    return (
      <Table
        selectable
        multiSelectable
        onRowSelection={(selectedUsers) => this._onRowSelection(selectedUsers, this.props)}
       >
         {/* contents */}
       </Table>
    )
  }
}

const filterUsers = (selectedUsers, deptAppRoles) => {
  if (selectedUsers === 'all') {
    return deptAppRoles
  } else if (selectedUsers === 'none') {
    return []
  } else if (selectedUsers === []) {
    return []
  } else {
    let users = []
    selectedUsers.map((num, i) => (
      users.push(deptAppRoles[num])
    ))
    return users
  }
}

applicable redux action that was passed down via props

export const selectedUsersAction = (users) => {
  console.log('selectedUsersAction', users)
  return dispatch => {
    dispatch({
      type: 'SELECTED_USERS',
      selectedUsers: users
    })
  }
}

applicable reducer

const admin = (state = { selectedUsers: [] }, action) => {
  switch (action.type) {
    // ...
    case 'SELECTED_USERS':
      return Object.assign({}, state, {
        selectedUsers: action.selectedUsers
      })
    default:
      return state
  }
}

screenshot
ignore the console errors, they are from something else.

I selected the first row, and the console registers that [0] was clicked, and my redux action registers who got clicked, but the checkbox doesn't update because my redux action (reducer) somehow blocked the component from rendering the updated checkbox.

enter image description here

Upvotes: 2

Views: 1935

Answers (1)

Dan Munday
Dan Munday

Reputation: 381

The problem here is that your reducer is working with an immutable state (by using Object.assign). This is a good way to write a reducer (or using spread notation), but it's causing a problem here.

When you set the new selectedUsers in the reducer you are also creating a new copy of state and replacing the old one. I'm guessing you are storing the actual data used to generate the table in same reducer as the selectedUsers (an array of user objects?). When you use Object.assign({}, state, etc.... you are creating new instances of every property on the state object. This includes the array of user objects used to generate the table rows.

The table component must be registering that this array is new and forcing a re-render or clearing the current selected state based on the fact that the array has been replaced.

I had the same problem and I started off with this fix -

const admin = (state = { selectedUsers: [] }, action) => {
 switch (action.type) {
  // ...
  case 'SELECTED_USERS':
   state.selectedUsers = action.selectedUsers
   return state
  default:
   return state
 }
}

It worked, but I didn't like it. So I opted to store my selectedUsers in a separate reducer to the actual user data used to generate the table and that also fixed my problem. It's not the best fix in the world, but it works and it's better than sacrificing immutability.

So for the time being I have a separate selected reducer for my different table views. I think I'll need to find a better solution in the long run.

Upvotes: 2

Related Questions