0
votes

I was going through the react document on Handling events at https://facebook.github.io/react/docs/handling-events.html

There was this part where the following line was mentioned: "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."

An example was provided on Codepen. I tried removing the bind by commenting out "this.handleClick = this.handleClick.bind(this);" and adding "console.log(this)" on the handleClick method. Here is the edited forked version: http://codepen.io/anakornk/pen/wdOqPO

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() {
    console.log(this);
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

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

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

According to the above statement in the doc, the output should be"undefined" , but "null" was shown instead.

Why is this?

1
I believe this is a discrepancy based on how React handles subclassing and components internally. Without React and just with ES6, it will be undefined when you don't call methods with context. - Andrew Li

1 Answers

1
votes

You could set a break point on this line and inspect call stack.

ReactErrorUtils.invokeGuardedCallback = function (name, func, a, b) {
  var boundFunc = func.bind(null, a, b); // <-- this is why context is null
  var evtType = 'react-' + name;
  fakeNode.addEventListener(evtType, boundFunc, false);
  var evt = document.createEvent('Event');
  evt.initEvent(evtType, false, false);
  fakeNode.dispatchEvent(evt);
  fakeNode.removeEventListener(evtType, boundFunc, false);
};

"use strict"

function fn() {
  return this;
}

console.log(fn(), fn.bind(null)())