3

Learning about handling events in React, can someone else how the binding works in both scenarios below? If you can reference the handleClick with this.handleClick, why do you still need to bind it? Wouldn't this inside the handler already be pointing to the component because it's the component who calls the handler? Also, why does placing the handler in an annonymous function also work?

You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.

The solution is this:

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

But why does this also work?

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // This syntax ensures `this` is bound within handleClick
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}
1

2 Answers 2

4

Because arrow functions (it is this in your case: (e) => this.handleClick(e)) will automatically "bind" this for you even if you don't call bind(this) on function. So here:

<button onClick={(e) => this.handleClick(e)}>
    Click me
</button>

The anonymous function is given the correct enclosing context (The LoginButton component in your case) automatically and it has handleClick method. And that's way it works.

And this way you can also make this this.handleClick = this.handleClick.bind(this); into an arrow function like this this.handleClick = () => this.handleClick; and get the same result.

Look here for detailed explanation:

An arrow function does not create its own this context, so this has the original meaning from the enclosing context.

Sign up to request clarification or add additional context in comments.

Comments

0

in javascript, "this" is dynamically scoped. That means,"this" inside handleClick changes depending on who calls it. it is not bound to any context. When you defined it inside class Login, "this" referred to Login class. then you are using handleClick inside button which is in the jsx world. At this point, ask yourself who is calling handleClick()? The answer is button element in jsx and now "this" inside handleClick refers to the button element. So what is happening here:

 this.handleClick = this.handleClick.bind(this)//(this) refers to class Login.

bind() method returns a new function and sets the context of "this". in this case we are saying that from now on this.handleClick is a different function. its "this" value will always refer to class Login

if you write it like this

this.handleClick = this.handleClick.bind(myObject); 

"this" would always refer to myObject

If you use "this" inside an arrow function, "this" will be lexically scoped, in other words locally scoped. it means no matter where you call the arrow handleClick(), "this" inside arrow function will always refer to context that it is created, which in your example is Login Class.

Comments

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.