Boky
Boky

Reputation: 12064

Checkbox in react js doesn't change

I have main component as follows :

export default class RegistrationFormStepFour extends React.Component{
constructor(props){
    super(props);
    this.state = {
        terms: false,
        emailNotifications: false,
        smsNotifications: false,
        errors: {}
    }
}


handleTerms(event){
    event.preventDefault();
    this.setState({terms: !this.state.terms});
}

render(){
    const language = this.props.currentLanguage;

    return (
        <div>
            <Terms
                nameYes="chcTerms"
                text={language.termsText}
                state={this.state.terms}
                onChange={this.handleTerms.bind(this)}
                currentLanguage={language}
                error={this.state.errors.terms}/>

        </div>
    );
}
}

And component term is as follows :

import React from 'react';

const Terms = ({nameYes, text, state, onChange, error}) => {

let hasError = error ? "hasError" : "";

return (
    <div className="col-lg-12 text-center" style={{marginBottom: 30}}>
        <form>
            <label className="radio-inline">
                <input
                    type="checkbox"
                    name={nameYes}
                    checked={state}
                    onChange={onChange}
                    value=""/>
            </label>
        </form>
        <p className={`questionsText ${hasError}`} style={{marginTop: 10}}>{text}</p>
    </div>
);
};

export default Terms;

But when I click on the checkbox, nothing happens. If I console log the state in the terms component it show right value. First time is false, when I click on the checkbox than is true, but the checkbox isn't checked.

Any advice?

Upvotes: 1

Views: 3729

Answers (2)

dting
dting

Reputation: 39287

The event.preventDefault() is causing your problems in the controlled component checkbox.

http://www.matthiaslienau.de/blog/tags/checkbox

Checkboxes (and Radio Buttons): Manually updating state fails for checkboxes (and without having tested it: I think for radio controls as well). Why? The problem one will face is that the checkbox onChange event behaves in a special way since the era of HTML (how could I forget!): You may not toggle the state of a checkbox manually via the .checked property. Nor does React. The onChange (onClick) event is fired after the element state changed internally. This may just be reverted based on the return value of the event handler. See this post for a comprehensive examination of this fact.

const Terms = ({ nameYes, text, state, onChange, error }) => {
  let hasError = error ? "hasError" : "";
  return (
    <div>
      <form>
        <label className="radio-inline">
          <input
            type="checkbox"
            name={nameYes}
            checked={state}
            onChange={onChange} 
          />
        </label>
      </form>
      <p className={`questionsText ${hasError}`}>{text}</p>
    </div>
  );
};

class RegistrationFormStepFour extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      terms: false,
      emailNotifications: false,
      smsNotifications: false,
      errors: {}
    }
  }

  handleTerms(event) {
    this.setState({ terms: event.target.checked });
  }

  render() {
    const language = { termsText: 'Some Language' };
    return (
      <div>
        <Terms
          nameYes="chcTerms"
          text={language.termsText}
          state={this.state.terms}
          onChange={this.handleTerms.bind(this)}
          currentLanguage={language}
          error={this.state.errors.terms}/>
       {JSON.stringify(this.state)}
      </div>
    );
  }
}

ReactDOM.render(<RegistrationFormStepFour />, document.getElementById('app'))
<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="app"></div>

Upvotes: 5

user5738822
user5738822

Reputation:

I think you should remove value attr from input tag. try this :

  <input
                        type="checkbox"
                        name={nameYes}
                        checked={state}
                        onChange={onChange}
                        />

Upvotes: 1

Related Questions