How is handleChange working?

Hey! I am wondering how the handleChange function receives its event parameter when called in the input element. And why do you not need to bind this to handleChange in onChange? I have seen people both binding it and not, and both seem to work. Here is my code:

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({
      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.bind(this)} />
        { /* Change code above this line */}
        <h4>Controlled Input:</h4>
        <p>{this.state.input}</p>
      </div>
    );
  }
};

How events work in JS:

Event reference:

In this case it’s a “change” event. If there is an event listener attached to the thing that gets clicked (there is, that’s what the onChange prop is), the function associated with the event listener fires, the argument to that function is the event object

this in JS is the value of the calling context. In JS it changes depending on where a function is called in the code. In this case you have a function called handleChange. You have an object ControlledInput. So ControlledInput.handleChange(), calling context is ControlledInput in the code you’ve got there, inside that object. [Edit for clarity: importantly, that object also has a property called state which you are modifying. It also has a property called setState, a function]

In React, what you tend to want to do is to pass functions to other components. So ControlledInput may use another component, a button maybe, ControlledInputButton. And you have a handleClick function that changes the state of ControlledInput, but you pass the function itself to ControlledInputButton and use it as that component’s useClick callback.

So click a button in the button component, it fires handleClick, that updates the controlled input component.

If you just pass the function, the context is now ControlledInputButton for handleClick. So when it tries to update state it’ll fail, wrong component [Edit for clarity: it’ll try to update ControlledInputButton.state instead of ControlledInput.state]

bind is a property (in this case a function) that is attached to all functions in JS. It creates a new function with a calling context specified.

So you can bind the handleClick callback to ControlledInput context, then pass that bound function to ControlledInputButton and it will work [edit for clarity: because now, when it executes, it executes in the context it’s bound to, so this in it refers to the correct object]

1 Like

Thank you a lot for the detailed answer, sir! it helped a lot! have a great day!

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.