3

I have a react component where I am iterating over a list and creating rows. In each row, there is a delete button. When the delete button is clicked, I want to pass a reference to the element in that row.

var TagTable = React.createClass({ onTagDelete: function(tagName) { this.props.onTagDelete(tagName); }, render: function () { return R.table({className: "bg-box padded"}, [ R.thead({}, R.tr({}, [ R.th({}, ""), R.th({}, "Tag"), R.th({}, "Regexes") ])), R.tbody({}, this.props.tags.map(function (tag) { return R.tr({}, [ R.td({}, R.button({onClick: function() {this.onTagDelete(tag.name)}.bind(this), // BIND className: "delete"}, "\u2716")), R.td({key: "name"}, tag.name), R.td({key: "regexes"}, tag.regexes.join(", "))]); }.bind(this))) // BIND ]) } } ); 

So in order to preserve the this-value in the click-handler; I use bind both for the map() and the click-handler.

Is this the proper way to pass arguments to handlers in React or is there a better way?

3
  • This (pun intended) is fine. Other way would be to use a closure var that = this and use that in the handler that.onTagDelete. Also pass your argument in the binding. Commented Oct 13, 2014 at 18:18
  • For what it's worth, people use .bind in nearly all of the components I've seen. It is just a code style difference. Commented Oct 13, 2014 at 19:32
  • map takes an optional second parameter that is used as the context for the function call, i.e. what "this" means. You can do .map(function() { ... }, this) instead of using bind. Commented Oct 13, 2014 at 21:00

2 Answers 2

3

I'm fairly new to react, but I figured I'd throw this out here to help.

I think you need to change this line,

R.td({}, R.button({onClick: function() {this.onTagDelete(tag.name)}.bind(this), // BIND className: "delete"}, "\u2716")), 

to

R.td({}, R.button({onClick: function() {this.onTagDelete.bind(this, tag.name)}, // BIND className: "delete"}, "\u2716")), 

I'm pretty sure that this should now pass the tag name to the function. Another way of getting data from the clicked subject is through refs, but with lists of items I don't think this works well because of repeated ref names. So I would just do what you are doing now.

Sign up to request clarification or add additional context in comments.

Comments

1

You can do less verbose:

 R.td({}, R.button({onClick: this.onTagDelete.bind(this, tag.name), // BIND className: "delete"}, "\u2716")), 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.