React - Create a Controlled Input

Tell us what’s happening:
Describe your issue in detail here.
what I am doing wrong here?

  **Your code so far**
class ControlledInput extends React.Component {
constructor(props) {
  super(props);
  this.state = {
    input: ''
  };
  // Change code below this line
this.handleChange=this.handleChange.bind(this)
  // Change code above this line
}
// Change code below this line
handleChange(event){

this.setState((state)=>{
  state.input=event.target.value;
})

}
// Change code above this line
render() {
  return (
    <div>
      { /* Change code below this line */}
<input value={this.state.input} onChange={(e)=>{this.handleChange(e)}}/>
      { /* Change code above this line */}
      <h4>Controlled Input:</h4>
      
      <p>{this.state.input}</p>
    </div>
  );
}
};
  **Your browser information:**

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36

Challenge: React - Create a Controlled Input

Link to the challenge:

setState should not directly change state. Never mutate state. Every time you do that, Dan Abramov kills a puppy. The callback function in setState should return an object that is what you want the knew state to be.

1 Like

in this problem I had directly mutated state visibility by toggling it by “=” sign, then how this was correct?

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      visibility: false
     
    };
    // Change code below this line
 this.toggleVisibility=this.toggleVisibility.bind(this)
    // Change code above this line
  }
  // Change code below this line
 toggleVisibility(){
   this.setState((state)=>{
     if (state.visibility===false){
       return state.visibility=true}
       else {
         return state.visibility=false;
       }
     })
 }
 
 
  // Change code above this line
  render() {
    if (this.state.visibility) {
      return (
        <div>
          <button onClick={this.toggleVisibility}>Click Me</button>
          <h1>Now you see me!</h1>
        </div>
      );
    } else {
      return (
        <div>
          <button onClick={this.toggleVisibility}>Click Me</button>
        </div>
      );
    }
  }
}

Where in the React curriculum did you see updating state like this?

this was my submitted succesfully solution from freecodecamp

The answer to my question is that no where in the React curriculum or docs does it show to update state this way. In fact, it says not to directly update state. You must return an object with the state properties and corresponding values to update state. That is what was taught.

You technically were returning an updated state property in the other one challenge, but that is a very unconventional way of do it and might not necessarily will work all the time. The only way to guarantee state properties get updated with the values you want, is to return an object.

ok so in React It should always return object with updated state? but why so?

and please tell me had I written onChange handler correctly or not?

is this correct way

 this.setState({input:event.target.value})

Correct. Why? Because. Or more accurately because that is how Redux was designed to work. Certain features of Redux will not work if you mutate state. Never, never do that. Always return the new state.

in setState method is callback function optional or every setState should have call back?

what is difference between

<input value={this.state.input} onChange={e=>{this.handleChange(e)}}/>

and this

<input value={this.state.input} onChange={this.handleChange}/>

because both ways it is working

The callback function is what you are passing to setState.

this.setState(state => ({ number: 0 }))

In this, state => ({ number: 0 }) is the callback.

1 Like

Yes, they both work, they both do the same thing. The difference is that the first one wraps it in an unnecessary extra function. I will almost always prefer the second one.

I’ve seen a few cases where the second won’t work, like if the function is from some library and it has optional other parameters, and the callback is getting sent other parameters so you need that extra layer to control what is getting passed. And of course if you need to pass in external parameters. But in general, the second option is cleaner.

I added [spoiler][/spoiler] tags since that is a working answer.

Yes, that works. You gave setState a new object. That is the right way to do it.

That is the old, “object” form of setState. Before you were trying the newer “functional” form of setState. The object form works in this case since the new state is not based on the old state, but you should learn the functional kind too. The difference is that instead of passing setState an object, you pass it a function that returns an object.

I’ve seen a few cases where the second won’t work, like if the function is from some library and it has optional other parameters, and the callback is getting sent other parameters so you need that extra layer to control what is getting passed..

.