True and false radio buttons in react

12,689

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>
    );
  }
} 
Share:
12,689

Related videos on Youtube

Munsterberg
Author by

Munsterberg

Updated on June 04, 2022

Comments

  • Munsterberg
    Munsterberg almost 2 years

    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?

    • Justin Herter
      Justin Herter over 7 years
      I have a feeling your if block in _handleRadio method is the culprit, try adding a console.log() in there to see if it is being hit and you are getting the proper value form your selection.
    • Munsterberg
      Munsterberg over 7 years
      @JustinHerter just tried it, everything seems to be firing. I thought the same thing at first
    • Justin Herter
      Justin Herter over 7 years
      Use the callback method of setState to check the value of isPublished after setting it, like this this.setState({isPublished: value}, function () { console.log("state: ", this.state)}); lets just make sure things are being set as we would expect then move on with the debugging.
    • Munsterberg
      Munsterberg over 7 years
      Good idea. Yeah its definitely logging the correct value. Even the console.log(sampleObj) returns the value, its not until grabbing the object after the redirect does the value change back to true.
    • Justin Herter
      Justin Herter over 7 years
      Is the _handleRadio method being fired on route change? Check your logs.
    • Munsterberg
      Munsterberg over 7 years
      Where can I go to check that? @JustinHerter because I dont believe it is
    • Justin Herter
      Justin Herter over 7 years
      Oh sorry just console.log at the top of the method and check after you submit. in fact console log everywhere and watch it as you step through the process. Unfortunately you will have to do the debugging =). Something is happening around the submission event either just prior, during, or after so just log everywhere and watch to see what is happening. Good luck.
    • Munsterberg
      Munsterberg over 7 years
      Thanks! After the console.logs i can see its happening after the submit, just not sure why. Im gonna keep digging away at it :), thanks for the tips!
    • D. Walsh
      D. Walsh over 7 years
      So sampleObj gives the correct value from state, but the received payload from api.post shows an incorrect value?
    • Munsterberg
      Munsterberg over 7 years
      Yeah sampleObj gives the correct value, but when I grab it with a get request using the id in another component, it returns to false. So sampleObj is definitely being sent with the correct data (and the false value for isPublished), but when I get the same entry from the api, isPublished is true @D.Walsh
    • D. Walsh
      D. Walsh over 7 years
      Wait, using what id? And from what component?
    • Munsterberg
      Munsterberg over 7 years
      so this this.context.router.push(${result.id}/); renders another component which calls the following: api.getJSON(samples/${this.props.params.id}) .done((result) => { console.log(result); this.setState({sample: result}); }); not really sure how to format in the comments
  • Munsterberg
    Munsterberg over 7 years
    This works great, but the real issue was in the API I was hitting. After doing some digging in their docs, I found it. Thanks for explaining the controlled vs uncontrolled though, needed that as I am fairly new to react
  • D. Walsh
    D. Walsh over 7 years
    Thanks, glad it helped!