9

I have multiple checkbox in my React Class B.js:

<input
   type="checkbox"
   inline={true}
   checked={this.props.checkBoxDefaultStatus}
   onChange={this.handleCheckBoxClick} 
/>

Now the prop checkBoxDefaultStatus is passed from parent class A.js.

A.js

this.state = {
  checkBoxDefaultStatus: false
}

handleMultiSelect() {
    this.setState({
        checkBoxDefaultStatus: true
    })
}

render() {
  <B checkBoxDefaultStatus={this.state.checkBoxDefaultStatus} />
}

EDIT: Now All my child checkboxes are getting checked when I click on parent checkbox, but the issue is that my child checked boxes checked status does not change when I click on them as they are already set by parent prop. I need some way to maintain this also.

This is the behaviour I want https://stackoverflow.com/a/35218069/6574017

User 101
  • 1,351
  • 3
  • 12
  • 18

3 Answers3

10

If you want change parent component state inside child component, then you have to pass parent component method to child component as props like below,

<B handleCheckBoxClick={this.handleMultiSelect}/>   

Check below working code. I build 2 component for your scenario.

class B extends React.Component {
   constructor(){
    super();
    this.state = {
      checkBoxClick : {
        1: false,
        2: false
      }
    }
    this.handleCheckBoxClick = this.handleCheckBoxClick.bind(this);
   }
   
   handleCheckBoxClick(no, event){
    //console.log('no', no);
    //console.log('event.target.value', event);
    var checkBoxClick = this.state.checkBoxClick;
    checkBoxClick[no] = !this.state.checkBoxClick[no];
    this.setState({
      checkBoxClick
    });
    
    var alltrue =Object.keys(checkBoxClick).every((k) =>{ return checkBoxClick[k] });
    //console.log('alltrue', alltrue);
    if(alltrue){
      // console.log('alltrue in if : ', alltrue);
      this.props.handleMultiSelect();
    }
    
    if(this.props.checkBoxDefaultStatus){
      this.props.handleMultiSelect();
    }
   }

  render(){
    //console.log('this.state.checkBoxClick :', this.state.checkBoxClick);
    //console.log('this.props.checkBoxDefaultStatus :', this.props.checkBoxDefaultStatus);
    return(
    <div>
    Child component check-box <br />
      <input
       type="checkbox"
       checked={this.props.checkBoxDefaultStatus ? this.props.checkBoxDefaultStatus : this.state.checkBoxClick[1]}
       onChange={(e) => {this.handleCheckBoxClick(1, e.target.checked)}} 
    /> Bar 1<br />
    <input
       type="checkbox"
       checked={this.props.checkBoxDefaultStatus ? this.props.checkBoxDefaultStatus : this.state.checkBoxClick[2]}
       onChange={(e) => {this.handleCheckBoxClick(2, e.target.checked)}} 
    /> Bar 2<br />
    </div>
    );
  }
}

class A extends React.Component {

  constructor() {
    super();
    this.state = {
      checkBoxDefaultStatus: false
    }
    
    this.handleMultiSelect = this.handleMultiSelect.bind(this);
  }

  handleMultiSelect() {
    //console.log('aaaa')
    this.setState({
      checkBoxDefaultStatus: !this.state.checkBoxDefaultStatus
    })
  }

  render() {
  //console.log('checkBoxDefaultStatus :', this.state.checkBoxDefaultStatus);

    return (
    <div>
      <input type="checkbox" onClick={() => {this.handleMultiSelect()}} checked={this.state.checkBoxDefaultStatus}/>
      Check all<br />
      <B checkBoxDefaultStatus={this.state.checkBoxDefaultStatus}
        handleMultiSelect={()=>{this.handleMultiSelect()}}
      />
      </div>
    );
  }
}

ReactDOM.render( < A / > , document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='root'></div>
Thilina Sampath
  • 3,615
  • 6
  • 39
  • 65
  • I have written exactly the same code, and all my child checkboxes are getting checked when I click on parent checkbox, but the issue is that my child checked boxes checked status does not change when I click on them as they are alreadt set by parent prop. I need some way to maintain this also. – User 101 Sep 03 '18 at 09:35
  • https://stackoverflow.com/questions/386281/how-to-implement-select-all-check-box-in-html#answer-35218069 same scenario do you want – Thilina Sampath Sep 03 '18 at 09:40
  • yes that's exactly what I want bbut in my case only checkAll works as individualk clicks does not work....how to do this in React – User 101 Sep 03 '18 at 09:40
  • is in your code checkAll in parent component and individual component in child component? – Thilina Sampath Sep 03 '18 at 09:43
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/179309/discussion-between-user-101-and-thilina-sampath). – User 101 Sep 03 '18 at 09:48
  • wait I will handle this – Thilina Sampath Sep 03 '18 at 09:53
  • please check and let me know – Thilina Sampath Sep 03 '18 at 11:36
3

Please using checked prop instead of defaultChecked like this:

<input
   type="checkbox"
   inline={true}
   checked={this.props.checkBoxDefaultStatus}
   onChange={this.handleCheckBoxClick} 
/>
Ali Torki
  • 1,929
  • 16
  • 26
  • 2
    Use `checked` for a controlled component and `defaultChecked` if you want an uncontrolled component. This is an important concept in react, and is explained here: https://reactjs.org/docs/uncontrolled-components.html _"In most cases, we recommend using controlled components to implement forms. In a controlled component, form data is handled by a React component. The alternative is uncontrolled components, where form data is handled by the DOM itself."_ – Håken Lid Sep 03 '18 at 09:40
  • @HåkenLid yeah I understood that but I think it was never the issue, what I want is this behaviour https://stackoverflow.com/a/35218069/6574017 but in my case since I am setting checked attribute using parent prop the child checkboxes are not unable to change itself. – User 101 Sep 03 '18 at 09:43
0

Its very simple. Use event.target.checked to know the checkbox status.

Example:

HTML: <input type="checkbox" onClick={(e) => OnCheckboxClick(e)}/> JS:

const OnCheckboxClick= (e) => {
    if(e.target.checked) {
        //blah blah
    }
    else {
       //blah blah
    }
}
Indranil
  • 2,229
  • 2
  • 27
  • 40