0

I'm actually trying to toggle a class on an element when user clicked. But unfortunately, my code only set class for single element. It looks like the view is not refreshing for subsequent clicks, even the set class is not removing. But my store is properly updating.

Here is my code.

class MyInterests extends Component {
    constructor(props) {
      super(props);
      this.state = {selected: []};
    }

    toggleChip(id, index, event){
        const { interestChanged } = this.props;
        let index = this.state.selected.indexOf(id);
        if(index === -1){
            this.state.selected.push(id);
        }else{
            this.state.selected.splice(index, 1);
        }
        interestChanged(this.state.selected);
    }

    render() {
    const {classes, myinterests: { categories, userinterest } } = this.props;
    const getClassNames = (id) => {
        return classNames(classes.chip, {[classes.selected]: (userinterest.indexOf(id) !== -1)});
    }
    return ( 
        /*..... Few element to support styles....*/
          {categories.map((data, index) => {
               return (
                 <Chip
                    key={data._id.$oid}
                    label={data.name}
                    onClick={this.toggleChip.bind(this, data._id.$oid, index)}
                    className={getClassNames(data._id.$oid)}
                  />
              );
       })}
);
  }
}

Can anyone tell me what is wrong in this or how can I achieve this?.

James
  • 2,874
  • 4
  • 30
  • 55

1 Answers1

1

Since state is immutable, you cannot use .push on it. By using this.state.selected.push(id) you're mutating the state thus not signaling react on the change making the change vulnerable to future state updates (remember that setState is asynchronous and changes are batched for single action).
Take a look at this for how to solve it. In your case, a better way to update the state would be something like this:

// create a copy of the current array
var selected = this.state.selected.slice();
// push the new element to the copy
selected.push(id);
// replace the current array with the modified copy
this.setState({ selected: selected });
Yoav
  • 3,326
  • 3
  • 32
  • 73
  • doesn't `interestChanged(this.state.selected);` alters the props and not the state? – Yoav Mar 27 '18 at 10:55