Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get reference to React component in event handler

Tags:

reactjs

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>         );     } }); 
like image 423
vbarbarosh Avatar asked Jan 20 '15 15:01

vbarbarosh


People also ask

How do I get reference to React component?

In order to get a reference to a React component, you can either use this to get the current React component, or you can use a ref to get a reference to a component you own. They work like this: var MyComponent = React. createClass({ handleClick: function() { // Explicitly focus the text input using the raw DOM API.

Can you pass ref to component?

Ref forwarding is a technique for automatically passing a ref through a component to one of its children. This is typically not necessary for most components in the application. However, it can be useful for some kinds of components, especially in reusable component libraries.

Can you add event listener to ref React?

To add an event listener to a ref in React: Set the ref prop on the element. Use the current property on the ref to get access to the element. Add the event listener in the useEffect hook.

How do you call a component onClick in React?

The React onClick event handler enables you to call a function and trigger an action when a user clicks an element, such as a button, in your app. Event names are written in camelCase, so the onclick event is written as onClick in a React app. In addition, React event handlers appear inside curly braces.


2 Answers

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!

like image 96
James Polanco Avatar answered Oct 02 '22 15:10

James Polanco


You'll have to propagate the handler to the root element of your child component, something like this:

var Foobar = React.createClass({     action: function (e) {         this.props.onClick(this);     },     render: function () {         return <div onClick={this.action}>{this.props.children}</div>;     } });  var App = React.createClass({     handleMouseEnter: function (foobar) {        console.log(foobar);     },     render: function () {         return (             <Foobar ref="foo" onClick={this.handleMouseEnter} />         );     } }); 
like image 41
tadeuzagallo Avatar answered Oct 02 '22 15:10

tadeuzagallo