OnClick Event binding in React.js

Since I see these kind of suggestions in multiple places, I am going to move my comment into an answer as well, to provide an additional view:

class TestComponent extends React.Component {
  constructor() {
    super();
    this.onClick = this.handleClick.bind(this);
  }

  handleClick(event) {
    const {id} = event.target;
    console.log(id);
  }

  render() {
    return (
      <div>
        <h3 id={this.props.id} onClick={this.onClick}>
          {this.props.name}
        </h3>
      </div>
    );
  }
}

This allows to:

  1. avoid unnecessary binds
  2. access the id and whatever else properties in a much more React-ive manner.

Of course, the above example assumes that you receive the id as a prop, but you can do the necessary manipulations as well.

UPDATE 1 -- Nov 28, 2016

Added link to CodePen from comments above.

UPDATE 2 -- Mar 30, 2017

As mentioned, this wouldn't work if you use React.createClass to define your components. You don't have a constructor to pull this off. You can use other lifecycle methods, if you don't mind a little ugliness.

Having said that, it is 2017. Use ES6, would you?!

UPDATE 3 -- May 12, 2017

If you are using class properties transform, then you can simplify it further:

class TestComponent extends React.Component {
  onClick = (event) => {
    const {id} = event.target;
    console.log(id);
  }

  render() {
    return (
      <div>
        <h3 id={this.props.id} onClick={this.onClick}>
          {this.props.name}
        </h3>
      </div>
    );
  }
}

UPDATE 4 -- Feb 4, 2018

Due to improvements of bind and friends in V8 (Chakra and such probably too), you just may be better off using the this.click.bind(this) or wrapping it in an arrow function when passing to onClick.

Why?

The previous method, created for performance reasons only, closed some possibilities for dynamically injecting functions onto the component's prototype.

NOTE 1 -- Apr 14, 2018

Keep in mind that the method mentioned in Update 4 still introduces some performance issues, as on each render pass a new function is created as a result of bind. This, in turn, will trickle down to the child component and cause unnecessary re-renders, as the function changes each time.

The same thing happens when you pass an arrow function inline.

All other methods, like using class properties, will mess with your inheritance (which you should be avoiding, but still), simply due to the fact that, currently, Babel transpiles them to "on-instance" functions, which are not on the prototype chain.

So, this:

class Person {
  printA = () => { console.log('a') }
}

becomes:

function _classCallCheck(instance, Constructor) {...abridged...}

var Person = function Person() {
  _classCallCheck(this, Person);

  this.printA = function () {
    console.log('a');
  };
};

viewMore = (i,j) => () => {
    console.log(i,j)
}

To pass parameters to event handlers we need to use currying. With the above method no new functions created all the time while render is called.