React: Create a Controlled Input challenge

Tell us what’s happening:
I can not type in the input box. And I’ve try change even “onchange” to “onChange” but not working. How to fix it?

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=> ({
input: event.target.value
}))};
// Change code above this line
render() {
  return (
    <div>
      { /* Change code below this line */}
      <input value = {this.state.input} onchange = {this.handleChange}/>
      { /* 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/87.0.4280.141 Safari/537.36.

Challenge: Create a Controlled Input

Link to the challenge:

Hi @thanhluu.ssd,

When using React you have to always use camelCase for naming events.

Regarding the error, the problem lies in handleChange method and the easiest fix is to pass a new state object to this.setState instead of passing updater function. Normally you would pass a function to this.setState when you want to compute next state using previous state. In this challenge however we don’t need previous state, so there is no need for that:

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

Why it doesn’t work with updater function though?

  1. React under the hood uses SyntheticEvent which is just a wrapper around the browser event.
  2. In React 16 and earlier (this challenge uses 16.4) these Synthetic Events are pooled, in other words, they are reused and are no longer available after event handler has been called.
  3. setState() does not immediately mutate the state.

Because of all the above:

handleChange(event) {

  // This updater function will not be called immediately,
  this.setState(state => ({
    // By the time it gets called the event will already be
    // pooled - meaning its properties will be nullified
    input: event.target.value
  });
};

On the other hand:

handleChange(event) {

  // Here again the state will not be updated immediately,
  // but this time we're passing an object
  this.setState({
    // and we set its properties when we still have access to
    // event object
    input: event.target.value
  });
};

This is not something that you have to worry about, because from React 17 there is no event pooling anymore.

Still if you would like to read more, here are some links:
No Event Pooling in React 17
SyntheticEvent
Event Pooling

1 Like

Thank you so much. I got it.