Search code examples
javascriptreactjsstatechecked

setState for clicked item only in react app


In my react app i have multiple checkboxes and I'm toggling the checked state using onClick, it's setting the state but it's changing it for all the checkboxes in the page, i want only the pressed one, here is the code:

Initial state:

state: {checked: false}

Checkbox:

return boxes.map(box => (
<Checkbox checked={this.state.checked} onClick={() => this.onCheck(box.id)} />
))

Function:

onCheck(id) { this.setState({ checked: !this.state.checked }); }

Solution

  • Then you'll have to have one state variable for each checkbox. For simplicity, let's put all booleans defining whether the n-th checkbox has been checked into a single array.

    You can write a minimal component like this:

    class App extends React.Component {
    
      constructor(props) {
        super(props);
        this.state = { boxes: [{id: 10}, {id: 20}] };
        this.state.checked = this.state.boxes.map(() => false);
        this.onCheck = this.onCheck.bind(this);
      }
      onCheck(id) {
        let index = this.state.boxes.findIndex(box => box.id==id);
        this.setState({
          checked: this.state.checked.map((c,i) => i==index ? !c : c)
        })
      }
      render() {
        return (<div>
          {this.state.boxes.map((box,i) => (
            <input
              key={box.id}
              type="checkbox"
              checked={this.state.checked[i]}
              onChange={() => this.onCheck(box.id)}
            />
          ))}
          <pre>this.state = {JSON.stringify(this.state,null,2)}</pre>
        </div>);
      }
    }
      
    ReactDOM.render(<App/>, document.querySelector('#root'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    
    <div id="root"></div>