Stateless, Stateful & How to Debug by console.log

Use a Ternary Expression for Conditional Rendering

I could not solve this problem, and the correct one is:

          this.state.userAge === ''
            ? buttonOne
            : this.state.userAge >= 18
              ? buttonTwo
              : buttonThree

What’s bugging me is that, if I did not check the answer, I quite probably won’t be able to get to that point, because I have been wrong from the onset: Assuming that after user input in the text, the this.state.input’s value and this.state.userAge’s value will remain instead of resetting (because I think this is a stateful component). The answer given clearly shows that my assumption was wrong.

My question is, is there a way to debug in this particular? I need to know how to check whether my assumptions are true when tackling a problem. I honestly have a vague idea on how to debug on things within/related to a class constructor.

I know my question is kind of not specific. I don’t know how to word it any better. Or may be there is any other useful advise, I really appreciate it. Thanks!

Tell us what’s happening:
Describe your issue in detail here.

  **Your code so far**

const inputStyle = {
width: 235,
margin: 5
};

class CheckUserAge extends React.Component {
constructor(props) {
  super(props);
  // Change code below this line
  this.state = {
    input: "",
    userAge: ""
  }
  // Change code above this line
  this.submit = this.submit.bind(this);
  this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
  this.setState({
    input: e.target.value,
    userAge: ''
  });
}
submit() {
  this.setState(state => ({
    userAge: state.input
  }));
}
render() {
  const buttonOne = <button onClick={this.submit}>Submit</button>;
  const buttonTwo = <button>You May Enter</button>;
  const buttonThree = <button>You Shall Not Pass</button>;
  return (
    <div>
      <h3>Enter Your Age to Continue</h3>
      <input
        style={inputStyle}
        type='number'
        value={this.state.input}
        onChange={this.handleChange}
      />
      <br />
      {/* Change code below this line */}
      {this.state.input == this.state.userAge ? buttonOne : this.submit && this.state.input >= 18 ? buttonTwo : buttonThree}
      {/* Change code above this line */}
    </div>
  );
}
}
  **Your browser information:**

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36

Challenge: Use a Ternary Expression for Conditional Rendering

Link to the challenge:

Lets dissect your ternary and its logic

Your first condition:

this.state.input == this.state.userAge

This is not immediately relevant, but in JavaScript you are almost always going to want to use this: === and not: ==.

Due to your first condition the only time buttonOne can render is when the input is empty because as soon as it is not this
this.state.input == this.state.userAge will be false, and only buttonOne has an onClick event so they other two buttons can’t actually do anything meaning that wether the first button is showing or not is purely due to the inputs onChange event which is not the desired effect.

Your next condition:
this.submit && this.state.input >= 18
The first half does nothing as this.submit is a function which is technically an object in JS and therefore a truthy value (you can do Boolean(this.submit) to check (you can also !!this.submit) )

The second half is fine, but this.state.input is a string so you may want to wrap it such as: Number(this.state.input) to be explicit and more clear

1 Like

I still can’t wrap my head around your first paragraph. I’ll try research some more. I got your second and third paragraph very clear. But thank you!

Think about why, and what of your pieces of state.

What(input):
You have state.input so you can control what the input.value is, and so you can update state.userAge when the onClick for button one goes off.

Why(input):
Controlling the inputs value through state is what makes it a controlled input of course, but the reason for it boils down to having a single source of truth that being the state. More on that here:

Going on next to using state.input to update state.userAge this only happens onClick and is more to the purpose of why we have userAge so I’ll talk on it latter.

What(userAge):
The state useAge is what should be in charge of what gets rendered where the button exists, and this primarily what is going wrong in your ternary as you rely on the state.input value which is not its purpose, but rather to do what I mentioned early.

Why(userAge):
State helps us render what we intend to and how we intend to do it. The reason we base the rendering of the buttons on userAge is because its value practically only changes due to the onClick event which is the desired outcome because onClick is when we want to decide wether the users are shown buttonTwo or buttonThree . (End)

It is very important to know why you have your pieces of state as you actually want to minimize state as much as possible, because state requires side effects and side effects can lead to errors.

To sum up that long winded story your logic in your ternary should rely on userAge as that is the relevant state.

1 Like

Ooh wow! Thanks a lot for breaking it down to this detail. It makes much more sense now, and this is really useful like forever. Thank you!

1 Like