Byrd
Byrd

Reputation: 907

Updating Redux store to remove something from array doesn't rerender

I am making a batch adding system. In the system I have a redux store property name addPlayerList. Here I will be placing all the Players that i will be batch adding. Now adding players to the add player list is not a problem, the state reflects the change and it renders the Material UI Chips correctly. However when i remove them via the Chips delete button, the state is reflected in my redux store but it does not rerender the page. So the player no longer exists in my store but he still showing up on the page.

If i run another search essentially causing something else to rerender it will fix the list properly. Any help with this issue would be greatly appreciated.

class AddPlayer extends Component {

  onClick = () => {
    let {addPlayerToList} = this.props;
    addPlayerToList();
  }

  handleRequestDelete(index) {
    //figure out who the sender of it is
    let {removePlayerFromList} = this.props;
    removePlayerFromList(index);
  }

  render() {
    let {addPlayerToList, addPlayerList} = this.props
    let renderPlayersToAdd = () => {
      if (addPlayerList.length === 0) {
        return (
          <p>No Players to add</p>
        )
      }

       return addPlayerList.map((Player, index) => {
        return (
        <Chip 
          key={index} 
          onRequestDelete={this.handleRequestDelete.bind(this, index)}>
          <Avatar src={getImageURL(Player.id)} />
          {Player.name}
        </Chip>
        );
      }) 
    }

    return (
      <div>
         <TypeAhead />
         <RaisedButton onClick={addPlayerToList} label="Add Player" /> 
         {renderPlayersToAdd()}
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    selectedSuggestion: state.selectedSuggestion,
    addPlayerList: state.addPlayerList
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    addPlayerToList(Player) {
      dispatch(actions.addPlayerToList(Player));
    },
    removePlayerFromList(index) {
      dispatch(actions.removePlayerFromList(index));
    }
  }
}

const mergeProps = (stateProps, dispatchProps, ownProps) => {
  return {
    addPlayerToList: () => dispatchProps.addPlayerToList(stateProps.selectedSuggestion),
    addPlayerList: stateProps.addPlayerList,
    removePlayerFromList: (index) => dispatchProps.removePlayerFromList(index)
  }
}

const AddPlayerWithMutation = graphql(AddPlayerMutation)(AddPlayer);
const AddPlayerWithMutationAndState = connect(mapStateToProps, mapDispatchToProps, mergeProps)(AddPlayerWithMutation);
export default AddPlayerWithMutationAndState;

Upvotes: 3

Views: 1338

Answers (1)

jonahe
jonahe

Reputation: 5000

In your reducer code for removePlayerFromList, make sure you're not mutating the original array. So don't use splice (with a "p" in it). Rather do something like this

function removeIndex(array, index) {
  return [
    ...array.slice(0,index),
    ...array.slice(index +1)
  ];
};

This will create a new array, without the value at the specified index. And that should cause a re-render.

I can't promise that this is where the bug lies, but it's my best bet.

Upvotes: 4

Related Questions