Skip to content

Commit f28ac0f

Browse files
committed
Condensed the two refs pages into a single refs page, added a note about stateless components having null references.
1 parent 4b6e5d0 commit f28ac0f

6 files changed

+100
-84
lines changed

docs/_data/nav_tips.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
title: Communicate Between Components
3131
- id: expose-component-functions
3232
title: Expose Component Functions
33-
- id: references-to-components
34-
title: References to Components
3533
- id: children-undefined
3634
title: this.props.children undefined
3735
- id: use-react-with-other-libraries

docs/docs/08.1-more-about-refs.md

Lines changed: 96 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,98 @@
11
---
22
id: more-about-refs
3-
title: More About Refs
3+
title: References to Components
44
permalink: more-about-refs.html
55
prev: working-with-the-browser.html
66
next: tooling-integration.html
77
---
8-
After returning the structure of your UI from the render method, you may find yourself wanting to "reach out" and invoke methods on component instances returned from `render()`. Often, doing something like this isn't necessary for making data flow through your application, 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.
8+
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 is ideally unnecessary (and should be avoided) 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), when using React components in a larger non-React application, or when transitioning your code to React.
99

10-
Consider the case, when you wish to tell an `<input />` element (that exists within your instances sub-hierarchy) to focus after you update its value to be the empty string, `''`.
10+
Consider the case, when you wish to tell an `<input />` element (that exists within your instances sub-hierarchy) to focus after you update its value to be the empty string, `''`. That is to say, we want to implement an imperative function that will reset your application's input field to the empty state. This is a reasonable use case for refs, and one which we will explore in a moment, but first we'll look at the various options for getting a reference.
11+
12+
## The ref returned from React.render
13+
14+
No to be confused with the `render()` function that you define on your component (and which returns a virtual DOM element), [React.render()](/react/docs/top-level-api.html#react.render) will return a reference to your component's **backing instance**.
15+
16+
17+
```js
18+
var myComponent = React.render(<MyComponent />, myContainer);
19+
```
20+
21+
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.
22+
23+
```js
24+
var myComponentElement = <MyComponent />; // This is just a ReactElement.
25+
26+
// Some code here...
27+
28+
var myComponentInstance = React.render(myComponentElement, myContainer);
29+
myComponentInstance.doSomething();
30+
```
31+
32+
> Note:
33+
>
34+
> This should only ever be used at the top level. Inside components, let your `props` and `state` handle communication with child components, or use one of the other methods of getting a ref (string attribute or callbacks).
35+
36+
37+
38+
## The ref Callback Attribute
39+
40+
React supports a very 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).
41+
42+
It's as simple as adding a `ref` attribute to anything returned from `render` by using an ES6 arrow function:
43+
44+
```html
45+
render: function() {
46+
return <TextInput ref={(c) => this._input = c} />;
47+
},
48+
componentDidMount: function() {
49+
this._input.focus();
50+
},
51+
```
52+
53+
or
54+
55+
```html
56+
render: function() {
57+
return (
58+
<TextInput
59+
ref={function(input) {
60+
if (input != null) {
61+
input.focus();
62+
}
63+
}} />
64+
);
65+
},
66+
```
67+
68+
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. 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.
69+
70+
You can access the component's DOM node directly by calling `React.findDOMNode(argumentToYourCallback)`.
71+
72+
73+
## The ref String Attribute
74+
75+
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.
76+
77+
1. Assign a `ref` attribute to anything returned from `render` such as:
78+
79+
```html
80+
<input ref="myInput" />
81+
```
82+
83+
2. In some other code (typically event handler code), access the **backing instance** via `this.refs` as in:
84+
85+
```javascript
86+
this.refs.myInput
87+
```
88+
89+
You can access the component's DOM node directly by calling `React.findDOMNode(this.refs.myInput)`.
90+
91+
92+
## A Complete Example
93+
94+
95+
Consider the case, when you wish to tell an `<input />` element (that exists within your instances sub-hierarchy) to focus after you update its value to be the empty string, `''`. That is to say, we want to implement an imperative function that will reset your application's input field to the empty state.
1196

1297
```javascript
1398
var App = React.createClass({
@@ -19,7 +104,7 @@ Consider the case, when you wish to tell an `<input />` element (that exists wit
19104
},
20105
clearAndFocusInput: function() {
21106
this.setState({userInput: ''}); // Clear the input
22-
// We wish to focus the <input /> now!
107+
// TODO: We wish to focus the <input /> now!
23108
},
24109
render: function() {
25110
return (
@@ -44,9 +129,14 @@ Notice how, in this example, we want to "tell" the input something - something t
44129
>
45130
> Remember, what you return from `render()` is not your *actual* rendered children instances. What you return from `render()` is merely a *description* of the children instances in your component's sub-hierarchy at a particular moment in time.
46131
47-
48132
This means that you should never "hold onto" something that you return from `render()` and then expect it to be anything meaningful.
49133

134+
> Note:
135+
>
136+
> The return value of `React.render()` can be null if the component you are rendering is a stateless function (undocumented feature), because the component does not have a backing instance. You can always wrap a stateless component in a standard composite component and attach a ref to the composite component.
137+
138+
139+
50140
```javascript
51141
// antipattern: This won't work.
52142
render: function() {
@@ -65,61 +155,6 @@ In this example, the `<input />` is merely a *description* of an `<input />`. Th
65155

66156
So how do we talk to the *real* backing instance of the input?
67157

68-
## The ref String Attribute
69-
70-
React supports a very special property that you can attach to any component that is output from `render()`. This special property allows you to refer to the corresponding **backing instance** of anything returned from `render()`. It is always guaranteed to be the proper instance, at any point in time.
71-
72-
It's as simple as:
73-
74-
1. Assign a `ref` attribute to anything returned from `render` such as:
75-
76-
```html
77-
<input ref="myInput" />
78-
```
79-
80-
2. In some other code (typically event handler code), access the **backing instance** via `this.refs` as in:
81-
82-
```javascript
83-
this.refs.myInput
84-
```
85-
86-
You can access the component's DOM node directly by calling `React.findDOMNode(this.refs.myInput)`.
87-
88-
89-
## The ref Callback Attribute
90-
91-
The `ref` attribute can be a callback function instead of a name. 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).
92-
93-
It's as simple as adding a `ref` attribute to anything returned from `render` by using an ES6 arrow function:
94-
95-
```html
96-
render: function() {
97-
return <TextInput ref={(c) => this._input = c} />;
98-
},
99-
componentDidMount: function() {
100-
this._input.focus();
101-
},
102-
```
103-
104-
or
105-
106-
```html
107-
render: function() {
108-
return (
109-
<TextInput
110-
ref={function(input) {
111-
if (input != null) {
112-
input.focus();
113-
}
114-
}} />
115-
);
116-
},
117-
```
118-
119-
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. 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.
120-
121-
122-
## Completing the Example
123158

124159
```javascript
125160
var App = React.createClass({
@@ -171,3 +206,4 @@ Refs are a great way to send a message to a particular child instance in a way t
171206
- *Never* access refs inside of any component's render method - or while any component's render method is even running anywhere in the call stack.
172207
- If you want to preserve Google Closure Compiler Crushing resilience, make sure to never access as a property what was specified as a string. This means you must access using `this.refs['myRefString']` if your ref was defined as `ref="myRefString"`.
173208
- If you have not programmed several apps with React, your first inclination is usually going to be to try 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. Placing the state there often eliminates any desire to use `ref`s to "make things happen" – instead, the data flow will usually accomplish your goal.
209+
- If you are using "stateless functions" (undocumented feature - you'll know if you're using them), there is no backing instance and therefore the return value of `React.render()` will be null. If you need to get the DOM node rendered by a stateless component, you will need to wrap the component in a new composite component and attach the ref to the composite component.

docs/docs/ref-01-top-level-api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ ReactComponent render(
8181
)
8282
```
8383

84-
Render a ReactElement into the DOM in the supplied `container` and return a reference to the component.
84+
Render a ReactElement into the DOM in the supplied `container` and return a [reference](/react/docs/more-about-refs.html) to the component (or returns null for stateless components).
8585

8686
If the ReactElement was previously rendered into `container`, this will perform an update on it and only mutate the DOM as necessary to reflect the latest React component.
8787

docs/tips/15-expose-component-functions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: Expose Component Functions
44
layout: tips
55
permalink: expose-component-functions.html
66
prev: communicate-between-components.html
7-
next: references-to-components.html
7+
next: children-undefined.html
88
---
99

1010
There's another (uncommon) way of [communicating between components](/react/tips/communicate-between-components.html): simply expose a method on the child component for the parent to call.

docs/tips/16-references-to-components.md

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,4 @@ prev: expose-component-functions.html
77
next: children-undefined.html
88
---
99

10-
If you're using React components in a larger non-React application or transitioning your code to React, you may need to keep references to components. `React.render` returns a reference to the mounted component:
11-
12-
```js
13-
var myComponent = React.render(<MyComponent />, myContainer);
14-
```
15-
16-
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.
17-
18-
```js
19-
var myComponentElement = <MyComponent />; // This is just a ReactElement.
20-
21-
// Some code here...
22-
23-
var myComponentInstance = React.render(myComponentElement, myContainer);
24-
```
25-
26-
> Note:
27-
>
28-
> This should only ever be used at the top level. Inside components, let your `props` and `state` handle communication with child components, and only reference components via [refs](/react/docs/more-about-refs.html).
10+
This page has moved to: [refs](/react/docs/more-about-refs.html).

docs/tips/17-children-undefined.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ id: children-undefined
33
title: this.props.children undefined
44
layout: tips
55
permalink: children-undefined.html
6-
prev: references-to-components.html
6+
prev: expose-component-functions.html
77
next: use-react-with-other-libraries.html
88
---
99

0 commit comments

Comments
 (0)