vbarbarosh vbarbarosh - 17 days ago 4
React JSX Question

Get reference to React component in event handler

I can attach my event handler to a React component. Is there a way to get a reference to this component inside event hander?

var Foobar = React.createClass({
action: function () {
// ...
},
render: function () {
var child = React.Children.only(this.props.children),
props = _.omit(this.props, 'children');
return React.addons.cloneWithProps(child, props);
}
});

var App = React.createClass({
handleMouseEnter: function (event) {
// How to get reference to Foobar without using this.refs['foo']?
// I need to call *action* on it.
},
render: function () {
return (
<div>
<Foobar ref="foo" onMouseEnter={this.handleMouseEnter}>
...
</Foobar>
</div>
);
}
});

Answer

I think I understand the question vbarbarosh is asking, or at least I had a similar one that led me to this post. So if this doesn't answer the original question hopefully it can help others who land here.

In my case I have a React component with n number of children for defining configuration options for a UI action. Each child has a different ref identifying what config option the input represents and I want to be able to directly access the ref so I can then call methods exposed on my child component. (I could expose data attrs and use jQuery to extract, but that seems like a lot of extra hoops & performance issues)

My first attempt was this:

...
<Config ref="showDetails" onChange={this.handleChange} />
<Config ref="showAvatar" onChange={this.handleChange} />
...

Ideally, I wanted to bind all the change events to a single handler, then extract the ref from the target that dispatched the event. Unfortunately the dispatched SyntheticEvent does not provide a way to get the ref of the target so I can't make a direct call to this.ref[name].methodIWantToCall().

What I did find was an article in the React docs that lead me to a solution:

https://facebook.github.io/react/tips/communicate-between-components.html

What we can do is take advantage of JavaScript binding and pass in additional arguments.

...
<Config ref="showDetails" onChange={this.handleChange.bind(this, 'showDetails')} />
...

Now in my handler I get the addition data and can access my refs:

handleChange: function(refName, event) {
  this.refs[refName].myMethodIWantToCall()
}

The trick is that when binding, the argument order is changed and the first argument is now the bound value passed in and the event is now the second argument. Hope that helps!