<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
This version of the event listener makes it clear that the deleteRow
method - whose implementation we are not shown - takes two parameters. id
is presumably some identifier for the row that should be deleted, whereas e
must be the actual event object (because this is always the argument provided by the browser to an event callback).
So this is the most explicit form. But note that if for some reason your code is running in an environment which doesn't support arrow functions (and you're not transpiling it first), this obviously won't work. And the arrow function may be needed because, without it, the this
inside the deleteRow
method won't be what you expect it to be, in particular things like this.setState
won't work.
Unless, that is, you've taken other steps to ensure that the this
inside deleteRow
will be correct, such as in your second example:
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
The bind method of a function object returns another, related, function, and has 2 handy properties. The first, and most relevant in the context of the above discussion, is the object to which the this
reference inside the function will then always refer to. You are "binding" the this
reference to always be what you say it is, under all circumstances. (Well unless you try to call the bound function as a constructor with new
, which I would argue is not something that you really would ever want to do.) So this avoids the "this
problem" you might otherwise have, without the need of any ES6-specific features (.bind
has been around since ES5).
The other useful feature of bind
, which is completely unrelated to how it binds this
, is that all the other parameters to .bind
are passed as parameters to the function, and if any are left over, they are taken as parameters to the newly-created "bound function". This is called "partial application" - you "partially apply" the function by passing it some of the arguments it wants, and then pass the others later when you call the newly-created function.
So in this case where deleteRow
will have a signature like this:
deleteRow(id, event) {...}
the function myThis.deleteRow.bind(myThis, myId)
will, as well as binding all occurences of this
inside deleteRow
to myThis
, creates a new function which takes a single argument, event
, and supply that as the second parameter to deleteRow
, with the first fixed as myId
. So when it's called as an event handler, and passed the event object, it behaves in exactly the same way as the arrow function version above - with the correct this
, the particular id
desired as the first argument, and the event as the second.
I think there's little doubt that the arrow function version should be the preferred option, being more explicit. And even if you can't do this, you can still avoid the partial application by:
- binding the function in the constructor:
this.deleteRow = this.deleteRow.bind.this
, and
- then using a "normal" anonymous function instead of the arrow function: `onClick={function(e) {this.deleteRow(id, e);}}