React passing parameter via onclick event using ES6 syntax
Remember that in onClick={ ... }
, the ...
is a JavaScript expression. So
... onClick={this.handleRemove(id)}
is the same as
var val = this.handleRemove(id);
... onClick={val}
In other words, you call this.handleRemove(id)
immediately, and pass that value to onClick
, which isn't what you want.
Instead, you want to create a new function with one of the arguments already prefilled; essentially, you want the following:
var newFn = function() {
var args = Array.prototype.slice.call(arguments);
// args[0] contains the event object
this.handleRemove.apply(this, [id].concat(args));
}
... onClick={newFn}
There is a way to express this in ES5 JavaScript: Function.prototype.bind
.
... onClick={this.handleRemove.bind(this, id)}
If you use React.createClass
, React automatically binds this
for you on instance methods, and it may complain unless you change it to this.handleRemove.bind(null, id)
.
You can also simply define the function inline; this is made shorter with arrow functions if your environment or transpiler supports them:
... onClick={() => this.handleRemove(id)}
If you need access to the event, you can just pass it along:
... onClick={(evt) => this.handleRemove(id, evt)}
Use the value attribute of the button element to pass the id, as
<button onClick={this.handleRemove} value={id}>Remove</button>
and then in handleRemove, read the value from event as:
handleRemove(event) {
...
remove(event.target.value);
...
}
This way you avoid creating a new function (when compared to using an arrow function) every time this component is re-rendered.
Use Arrow function like this:
<button onClick={()=>{this.handleRemove(id)}}></button>
onClick={this.handleRemove.bind(this, id)}
Using with arrow function
onClick={()=>{this.handleRemove(id)}}
Something nobody has mentioned so far is to make handleRemove return a function.
You can do something like:
handleRemove = id => event => {
// Do stuff with id and event
}
// render...
return <button onClick={this.handleRemove(id)} />
However all of these solutions have the downside of creating a new function on each render. Better to create a new component for Button which gets passed the id
and the handleRemove
separately.