After building your component, you may find yourself wanting to "reach out" and invoke methods on component instances returned from render()
. In most cases, this should be unnecessary because the reactive data flow always ensures that the most recent props are sent to each child that is output from render()
. However, there are a few cases where it still might be necessary or beneficial, so React provides an escape hatch known as refs
. These refs
(references) are especially useful when you need to: find the DOM markup rendered by a component (for instance, to position it absolutely), use React components in a larger non-React application, or transition your existing codebase to React.
Let's look at how to get a ref, and then dive into a complete example.
Not to be confused with the render()
function that you define on your component (and which returns a virtual DOM element), ReactDOM.render() will return a reference to your component's backing instance (or null
for stateless components).
var myComponent = ReactDOM.render(<MyComponent />, myContainer);
Keep in mind, however, that the JSX doesn't return a component instance! It's just a ReactElement: a lightweight representation that tells React what the mounted component should look like.
var myComponentElement = <MyComponent />; // This is just a ReactElement.
// Some code here...
var myComponentInstance = ReactDOM.render(myComponentElement, myContainer);
myComponentInstance.doSomething();
Note:
This should only ever be used at the top level. Inside components, let your
props
andstate
handle communication with child components, or use one of the other methods of getting a ref (string attribute or callbacks).
React supports a special attribute that you can attach to any component. The ref
attribute can be a callback function, and this callback will be executed immediately after the component is mounted. The referenced component will be passed in as a parameter, and the callback function may use the component immediately, or save the reference for future use (or both).
It's as simple as adding a ref
attribute to anything returned from render
:
render: function() {
return (
<TextInput
ref={function(input) {
if (input != null) {
input.focus();
}
}} />
);
},
or using an ES6 arrow function:
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
When attaching a ref to a DOM component like <div />
, you get the DOM node back; when attaching a ref to a composite component like <TextInput />
, you'll get the React class instance. In the latter case, you can call methods on that component if any are exposed in its class definition.
Note that when the referenced component is unmounted and whenever the ref changes, the old ref will be called with null
as an argument. This prevents memory leaks in the case that the instance is stored, as in the first example. Also note that when writing refs with inline function expressions as in the examples here, React sees a different function object each time so on every update, ref will be called with null
immediately before it's called with the component instance.
React also supports using a string (instead of a callback) as a ref prop on any component, although this approach is mostly legacy at this point.
Assign a ref
attribute to anything returned from render
such as:
<input ref="myInput" />
In some other code (typically event handler code), access the backing instance via this.refs
as in:
var input = this.refs.myInput;
var inputValue = input.value;
var inputRect = input.getBoundingClientRect();
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.
if (this.myTextInput !== null) {
this.myTextInput.focus();
}
},
render: function() {
// The ref attribute is a callback that saves a reference to the
// component to this.myTextInput when the component is mounted.
return (
<div>
<input type="text" ref={(ref) => this.myTextInput = ref} />
<input
type="button"
value="Focus the text input"
onClick={this.handleClick}
/>
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);
In this example, we get a reference to the text input backing instance and we call focus()
when the button is clicked.
For composite components, the reference will refer to an instance of the component class so you can invoke any methods that are defined on that class. If you need access to the underlying DOM node for that component, you can use ReactDOM.findDOMNode as an "escape hatch" but we don't recommend it since it breaks encapsulation and in almost every case there's a clearer way to structure your code within the React model.
Refs are a great way to send a message to a particular child instance in a way that would be inconvenient to do via streaming Reactive props
and state
. They should, however, not be your go-to abstraction for flowing data through your application. By default, use the Reactive data flow and save ref
s for use cases that are inherently non-reactive.
this.refs.myTypeahead.reset()
). In most cases, it's clearer to use the built-in React data flow instead of using refs imperatively.<input />
and accessing its underlying DOM node using a ref. Refs are one of the only practical ways of doing this reliably.this.refs['myRefString']
if your ref was defined as ref="myRefString"
.ref
s to "make things happen" – instead, the data flow will usually accomplish your goal.