-2

could someone explain to me why i need to use binding this.handleClick = this.handleClick.bind(this); when using event?

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);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);

And why the value of 'this' is defined?

class Person {
    constructor(name, yearOfBirth) {
        this.name = name;
        this.yearOfBirth = yearOfBirth;
    }

    calculateAge() {
        console.log(this);
    }
}

const john = new Person('John', 1993);
john.calculateAge();

But the value of 'this' is undefined when clicked?

function ActionLink() {
    function handleClick(e) {
      e.preventDefault();
      console.log('The link was clicked.');
      console.log(this);
    }

    return (
      <a href="#" onClick={handleClick}>
        Click me
      </a>
    );
}

ReactDOM.render(
    <ActionLink />,
    document.getElementById('root')
);
boosted_duck
  • 478
  • 3
  • 15

2 Answers2

2

this is always executed in the context of where the function was invoked.

So when a React component renders, the elements and the event handlers will be attached to the DOM and will be executed in the DOM's context. So if you don't bind the method to the component, you cannot use this inside the method.

// this will be window and window.setState will be undefinedd
this.setState(state => ({
  isToggleOn: !state.isToggleOn
}));

When you bind the method to the Component, this will execute in the Component's context and you will be able to invoke .setState.

Interestingly, if your method doesn't use any this invocations, you won't have any problems even if you don't bind.

As quirimmo pointed out in the comments, in strict mode, this will be undefined by default and ES6 Classes are executed in strict mode by default even if not specified explicitely. That's why this will be undefined if not bound to the class.

Dinesh Pandiyan
  • 5,814
  • 2
  • 30
  • 49
  • 2
    In strict mode, this will be undefined. Even in non strict mode, classes are executed as in strict mode. That s why it prints undefined and not the window object inside a react class method – quirimmo Dec 18 '18 at 03:34
  • Thanks, this is the exact answer i was looking for, they are in different execution context since the Component is rendered in the DOM. – boosted_duck Dec 18 '18 at 03:48
0

This is undefined in the snippets you've posted for just that reason, they are undefined.

In the first, you ask why you need to for the function to work- its because you're trying to call the components 'this' to call set state. So to do that you just bind this from the components constructor so that when you call that function 'this' is defined and set to the components 'this'.

J Livengood
  • 2,729
  • 1
  • 12
  • 26