anakornk
anakornk

Reputation: 48

React: When not bound, 'this' is null instead of undefined in React component event handler

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?

Upvotes: 0

Views: 466

Answers (1)

Yury Tarabanko
Yury Tarabanko

Reputation: 45121

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)())

Upvotes: 1

Related Questions