2

While learning React I came upon the finding that for some reason it doesn't do booleans the way I'm used to and I cannot seem to understand it.

I've tried a couple of methods to fix it but without success and I'm basically about to give up on React. jQuery is much much easier for me.

I understand that React saves the false value as a string to state and then interprets it as truthy. But I haven't managed to find a way to either save it as boolean or convert it to boolean.

Has React even heard of Boolean?!?!

Have a look at the fiddle and please tell me what I'm missing...or at least point me in the right direction. Been losing my mind on this for a whole day.

https://jsfiddle.net/nicholas_cb/btye84j2/14/

function Options(props) {

    /* TRIED TO FIX IT THIS WAY SO AS TO SET CHECKD VALUES TO BOOLEAN INSTEAD OF STRING AND CHANGING THE CHECKED VALUE TO LOCAL VARIABLES -- OBVIOUSLY DIDN'T WORK... x_X

    let optionValue1 = (props.optionValue1 == true);
    let optionValue2 = (props.optionValue2 == true);

    */

    console.log("Options received: optionValue1 = " + props.optionValue1 + " optionValue2 = " + props.optionValue2);
        let result = "Options received: optionValue1 = " + props.optionValue1 + " optionValue2 = " + props.optionValue2;
    
    return (
    <div>
    <br/>
    <label>{result}</label>
    <br/><br/>
    <label>Option One</label><input name="optionValue1" type="checkbox" checked={props.optionValue1} onChange={props.handleChange}/>
        <label>Option Two</label><input name="optionValue2" type="checkbox" checked={props.optionValue2} onChange={props.handleChange}/>
      </div>
    )
    
}

class Form extends React.Component {
   constructor(props){
       super(props)
   }

    render() {
    if(this.props.optionValue1 == true && this.props.optionValue2 == true) {
    console.log("TRUE/TRUE");
    return (
     <Options 
       optionValue1 = {this.props.optionValue1}
       optionValue2 = {this.props.optionValue2}
       handleChange = {this.props.handleChange}
     />
    )
    }
    
        if(this.props.optionValue1 == false && this.props.optionValue2 == true) {
    console.log("FALSE/TRUE");
    return (
     <Options 
       optionValue1 = {this.props.optionValue1}
       optionValue2 = {this.props.optionValue2}
       handleChange = {this.props.handleChange}
     />
    )
    }
    
        if(this.props.optionValue1 == false && this.props.optionValue2 == false) {
    console.log("FALSE/FALSE");
    return (
     <Options 
       optionValue1 = {this.props.optionValue1}
       optionValue2 = {this.props.optionValue2}
       handleChange = {this.props.handleChange}
     />
    )
    }
    
        if(this.props.optionValue1 == true && this.props.optionValue2 == false) {
    console.log("TRUE/FALSE");
    return (
     <Options 
       optionValue1 = {this.props.optionValue1}
       optionValue2 = {this.props.optionValue2}
       handleChange = {this.props.handleChange}
     />
    )
    }
    
    console.log("Matched no case.");
    return (
      <Options 
       optionValue1 = {this.props.optionValue1}
       optionValue2 = {this.props.optionValue2}
       handleChange = {this.props.handleChange}
     />
    )
  }

  
}

class FormContainer extends React.Component {

constructor(props) {
  super(props)

  this.state = {
    optionValue1: true,
    optionValue2: true,
  }

  this.handleChange = this.handleChange.bind(this)

}

    handleChange(event) {

        if(event.target.type == 'checkbox'){
            console.log("Checkbox changing: " + event.target.name);
            console.log("New value: " + event.target.checked);
            
                event.target.value = event.target.checked;
                        
        }

        const {name, value} = event.target
        
        this.setState({
            [name]: value
        })
    }

  render() {
    return (
        <Form
        handleChange={this.handleChange}
        optionValue1={this.state.optionValue1}
        optionValue2={this.state.optionValue2}
      />
    )
  }
}

ReactDOM.render(
  <FormContainer />,
  document.getElementById('container')
);

I've output all cases to console such as TRUE/TRUE, FALSE/TRUE, etc. It's also surprising to me that for some reason it comes across the matched none case? What's up with that? Where's that coming from? If it interprets it as truthy/falsy shouldn't it always match one of the cases?

Thanks

4
  • React is just a javascript framework. It's javascript. It saves in state whatever you tell it to save to state, so if boolean values are getting converted/coerced/etc into strings it is your code doing that. It's also why you should very nearly always use === for comparisons instead of ==. Commented Apr 15, 2020 at 7:07
  • for every case if () you are returning same output. Why? Commented Apr 15, 2020 at 7:12
  • 1
    The if conditional tests also don't match the console log output. In JS you also don't generally directly compare to true or false, but use the fact that the variables being used in the conditionals are already booleans, i.e. true or false. Commented Apr 15, 2020 at 7:18
  • @DrewReese That's true thanks for pointing that out. My bad...was kind of in a hurry and messed up the conditions a bit. Fixed now. Commented Apr 15, 2020 at 12:24

1 Answer 1

2

I just spent my 10 minutes so you don't get disappointed from React. It's way better than jQuery

First of all, use some better tools than jsfiddle. it is not for react development, it is just for code which can be written badly in one file. Use Codesandbox.io

Check this sandbox and let me know if still there is confusion

https://codesandbox.io/s/dazzling-bassi-l7pg8?file=/src/App.js

What you are doing wrong is that you are using state values to check/uncheck checkboxes but in handleChange callback

handleChange(event) {
        if(event.target.type == 'checkbox'){
            // This is wrong, don't change dom yourself if you are using controlled component
           // https://medium.com/@AndrewBonner2/controlled-components-in-react-920f3e795d87
            event.target.value = event.target.checked; 
        }
        // const {name, value} = event.target;
        // SHould be 
        // const { name, checked } = event.target;
        this.setState({
            // [name]: value
            // SHould be
             [name]: checked 
        })
    }
Sign up to request clarification or add additional context in comments.

10 Comments

That just looks like OPs code now running in a codesandbox. What is different? How is this an answer? Is there a second of all?
OP was assigning e.target.value = e.target.checked something like that, that was wrong, I fixed that
He was using state and then again setting values using e.target
@ZohaibIjaz Thank you man. Really enlightened me on this. Even though I was changing the actual value of the input with the e.target.value = e.target.checked for some reason it wasn't registering as such in my brain even though I know I shouldn't do that in react. My bad. But the real eye opener was the e.target.checked. That's all that's actually needed. I should have stored the checked value to the checked state. And this fact means I need to look deeper into this state thing to avoid something like this in the future. Thanks man.Life saver.Valuable 10 min. I'm sticking to react. :))
I changed the code to ` if(event.target.type == 'checkbox'){ const {name, checked} = event.target this.setState({ [name]: checked }) }else{ const {name, value} = event.target this.setState({ [name]: value }) } `
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.