You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
3.6 KiB
93 lines
3.6 KiB
8 years ago
|
---
|
||
|
id: refs-and-the-dom
|
||
|
title: Refs and the DOM
|
||
|
redirect_from: "/docs/working-with-the-browser.html"
|
||
|
redirect_from: "/docs/more-about-refs.html"
|
||
|
redirect_from: "/tips/expose-component-functions.html"
|
||
|
redirect_from: "/tips/children-undefined.html"
|
||
|
permalink: docs/refs-and-the-dom.html
|
||
|
---
|
||
|
|
||
|
In the typical React dataflow, [props](/react/docs/components-and-props.html) are the only way that parent components interact with their children. To modify a child, you re-render it with new props. However, there are a few cases where you need to imperatively modify a child outside of the typical dataflow. The child to be modified could be an instance of a React component, or it could be a DOM element. For both of these cases, React provides an escape hatch.
|
||
|
|
||
|
## The ref Callback Attribute
|
||
|
|
||
|
React supports a special attribute that you can attach to any component. The `ref` attribute takes a callback function, and the callback will be executed immediately after the component is mounted or unmounted.
|
||
|
|
||
|
When the `ref` attribute is used on a HTML element, the `ref` callback receives the underlying DOM element as its argument. For example, this code uses the `ref` callback to store a reference to a DOM node:
|
||
|
|
||
|
```javascript
|
||
|
class CustomTextInput extends React.Component {
|
||
|
constructor(props) {
|
||
|
super(props);
|
||
|
this.focus = this.focus.bind(this);
|
||
|
}
|
||
|
|
||
|
focus() {
|
||
|
// Explicitly focus the text input using the raw DOM API
|
||
|
this.textInput.focus();
|
||
|
}
|
||
|
|
||
|
render() {
|
||
|
// Use the `ref` callback to store a reference to the text input DOM
|
||
|
// element in this.textInput
|
||
|
return (
|
||
|
<div>
|
||
|
<input type="text" ref={(input) => this.textInput = input} />
|
||
|
<input
|
||
|
type="button"
|
||
|
value="Focus the text input"
|
||
|
onClick={this.focus}
|
||
|
/>
|
||
|
</div>
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
React will call the `ref` callback with the DOM element when the component mounts, and call it with `null` when it unmounts.
|
||
|
|
||
|
Using the `ref` callback just to set a property on the class is a common pattern for accessing DOM elements. If you are currently using `this.refs.myRefName` to access refs, we recommend using this pattern instead.
|
||
|
|
||
|
When the `ref` attribute is used on a custom component, the `ref` callback receives the mounted instance of the component as its argument. For example, if we wanted to wrap the `CustomTextInput` above to simulate it being clicked immediately after mounting:
|
||
|
|
||
|
```javascript
|
||
|
class AutoFocusTextInput extends React.Component {
|
||
|
componentDidMount() {
|
||
|
this.textInput.focus();
|
||
|
}
|
||
|
|
||
|
render() {
|
||
|
return <CustomTextInput ref={(input) => this.textInput = input} />;
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
You may not use the `ref` attribute on functional components because they don't have instances. You can, however, use the `ref` attribute inside the `render` function of a functional component:
|
||
|
|
||
|
```javascript
|
||
|
function CustomTextInput(props) {
|
||
|
// textInput must be declared here so the ref callback can refer to it
|
||
|
let textInput;
|
||
|
|
||
|
function handleClick() {
|
||
|
textInput.focus();
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<div>
|
||
|
<input type="text" ref={(input) => textInput = input} />
|
||
|
<input
|
||
|
type="button"
|
||
|
value="Focus the text input"
|
||
|
onClick={handleClick}
|
||
|
/>
|
||
|
</div>
|
||
|
);
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Don't Overuse Refs
|
||
|
|
||
|
Your first inclination may be to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy - see the [Lifting State Up](/react/docs/lifting-state-up.html) guide for examples of this.
|