Jake Jake - 1 month ago 20
Javascript Question

True and false radio buttons in react

Here is my current code:

The state in my component

this.state = {
name: '',
sample: '',
description: '',
isPublished: null,

};


Here is the handler for the radio buttons

_handleRadio(event) {
let value = true;
if (typeof event.currentTarget.value === 'string') {
(event.currentTarget.value === 'true' ? value = true : value = false );
}
this.setState({isPublished: value});
}


And finally here are my radio buttons

<div className="radio">
<label><input type="radio" name="isPublished" value="true" onChange={this._handleRadio} />Yes</label>
</div>
<div className="radio">
<label><input type="radio" name="isPublished" value="false" onChange={this._handleRadio} />No</label>
</div>


Sorry for the poor formatting, copy and pasting my code over here didn't turn out so well. When I try to fix it, I mess it up even more.

So right now, as is, the state is being changed, which is exactly what I want. But when I submit and make the POST request to my api, the isPublished state returns to true.

Here is my submit handler

_handleSubmit(event) {
event.preventDefault();
event.stopPropagation();
const sampleObj = this.state;
console.log(sampleObj);

api.post('samples', sampleObj).done((result) => {
console.log('Sample Saved!');
this.context.router.push(`${result.id}/`);
}).fail((error) => {
console.log('failed');
console.log(error);
});
}


Why does the state of isPublished return to true during the submit, even after changing it to false?

Answer

I think that there are a few structural problems. It's hard to tell without a bin, but here's what I see...

First, you're mixing uncontrolled components with controlled methods. E.g., you're not setting the checked attribute on the radio buttons (controlled), but you're also not checking the refs (or setting them) for values (uncontrolled). There should be a checked attribute for controlled.

Second, there's a lot of string to boolean mismatching. Assuming true and false are the only values for these buttons, try:

const isPublished = event.currentTarget.value === 'true' ? true: false;

I put it together in a pen.

https://codepen.io/anon/pen/pNooXq?editors=0010

class Form extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
            name: '',
            sample: '',
            description: '',
            isPublished: null,

        };
    this._handleRadio = this._handleRadio.bind(this);
    this._handleSubmit = this._handleSubmit.bind(this);
  }

  _handleRadio(event) {
    const isPublished = event.currentTarget.value === 'true' ? true: false;
    console.log('handle', isPublished);
    this.setState({ isPublished });
  }
  _handleSubmit(event) {
        event.preventDefault();
        event.stopPropagation();
        const sampleObj = this.state;
        console.log(sampleObj);
    }

  render() {
    const { isPublished } = this.state;
    console.log(isPublished, true);
    return (
      <form onSubmit={this._handleSubmit}>
        <div className="radio">
          <label>
            <input 
              type="radio" 
              name="isPublished" 
              value="true"
              checked={isPublished === true}
              onChange={this._handleRadio} />
            Yes
          </label>
       </div>
       <div className="radio">
         <label>
           <input 
             type="radio" 
             name="isPublished" 
             value="false"
             checked={isPublished === false}
             onChange={this._handleRadio} />
           No
         </label>
       </div>
        <button type="submit">Submit</button>
    </form>
    );
  }
}