Browse Source

Reorg docs, write a lot of content, import a lot of stuff from dex

main
petehunt 11 years ago
parent
commit
988efdee73
  1. 14
      docs/refactor/00-table-of-contents.md
  2. 2
      docs/refactor/02-displaying-data.md
  3. 6
      docs/refactor/03-interactivity-and-dynamic-uis.md
  4. 69
      docs/refactor/04-scaling-up.md
  5. 86
      docs/refactor/05-building-effective-reusable-components.md
  6. 119
      docs/refactor/06-forms.md
  7. 113
      docs/refactor/07-working-with-the-browser.md
  8. 130
      docs/refactor/07.1-more-about.refs.md

14
docs/refactor/00-table-of-contents.md

@ -19,7 +19,7 @@ Displaying data
- Components are just functions
- JSX syntax (link to separate doc?)
Handling user input
Interactivity and dynamic UIs
- Click handler example
- Event handlers / synthetic events (link to w3c docs)
- Under the hood: autoBind and event delegation (IE8 notes)
@ -32,22 +32,25 @@ Scaling up: using multiple components
- Motivation: separate concerns
- Composition example
- Ownership (and owner vs. parent)
- Children
- Data flow (one-way data binding)
- A note on performance
Building effective reusable components
- You should build a reusable component library (CSS, testing etc)
- Prop validation
- Transferring props: a shortcut
- Mixins
- Testing
Forms
- TODO list example
- How to think about Reactive forms
- New form events and properties
Working with the browser
- The mock DOM
- Refs / getDOMNode()
- More about refs
- Component lifecycle
- Polyfills
- Browser support and polyfills
Integrating with other UI libraries
- Using jQuery plugins
@ -78,3 +81,4 @@ Reference
- API
- DOM differences
- JSX gotchas
- Antipatterns

2
docs/refactor/02-displaying-data.md

@ -53,6 +53,8 @@ setInterval(function() {
View the finished code in a web browser and type your name into the text field. Notice that React is only changing the time string in the UI -- any input you put in the text field remains, even though you haven't written any code to manage this behavior. React figures it out for you and does the right thing.
The way it is able to figure this out is that React does not directly manipulate the DOM, **it uses a fast, internal mock DOM to perform diffs and computes the most efficient DOM mutation for you.**
The inputs to this component are called `props` -- short for "properties". They're passed as attributes in JSX syntax. You should think of these as immutable within the component, that is, **never write to this.props**.
## Components are just like functions

6
docs/refactor/03-handling-user-input.md → docs/refactor/03-interactivity-and-dynamic-uis.md

@ -1,4 +1,4 @@
# Handling User Input
# Interactivity and dynamic UIs
You've already [learned how to display data](./02-displaying-data.html) with React. Now let's look at how to make our UIs interactive.
@ -34,6 +34,8 @@ React.renderComponent(
With React you simply pass your event handler as a camelCased prop similar to how you'd do it in normal HTML. React ensures that all events behave identically in IE8 and above by implementing a synthetic event system. That is, React knows how to bubble and capture events according to the spec, and the events passed to your event handler are guaranteed to be consistent with [the W3C spec](http://www.w3.org/TR/DOM-Level-3-Events/), regardless of which browser you're using.
**If you'd like to use React on a touch device** (i.e. a phone or tablet), simply call `React.initializeTouchEvents(true);` to turn them on.
## Under the hood: autoBind and event delegation
Under the hood React does a few things to keep your code performant and easy to understand.
@ -62,4 +64,4 @@ A common pattern is to create several stateless components that just render data
## What should go in state?
**`this.state` should contain any data that the component's event handlers will change that should trigger a UI update.** In real apps this data tends to be very small and JSON-serializable. When building a stateful component, think about the minimal possible representation of its state, and only store those properties in `this.state`. Inside of `render()` simply compute any other information you need based on this state. You'll find that thinking about and writing applications in this way tends to lead to the most correct application, since adding redundant or computed values to state means that you need to explicitly keep them in sync rather than rely on React computing them for you.
**`this.state` should contain any data that the component's event handlers will change that should trigger a UI update.** In real apps this data tends to be very small and JSON-serializable. When building a stateful component, think about the minimal possible representation of its state, and only store those properties in `this.state`. Inside of `render()` simply compute any other information you need based on this state. You'll find that thinking about and writing applications in this way tends to lead to the most correct application, since adding redundant or computed values to state means that you need to explicitly keep them in sync rather than rely on React computing them for you.

69
docs/refactor/04-scaling-up.md

@ -54,30 +54,71 @@ In the above example, instances of `Avatar` *own* instances of `ProfilePic` and
It's important to draw a distinciton between the owner-ownee relationship and the parent-child relationship. The owner-ownee relationship is specific to React, while the parent-child relationship is simply the one you know and love from the DOM. In the example above, `Avatar` owns the `div`, `ProfilePic` and `ProfileLink` instances, and `div` is the **parent** (but not owner) of the `ProfilePic` and `ProfileLink` instances.
## Data flow
## Children
In React, data flows from owner to owned component through `props` as discussed above. This is effectively one-way data binding: owners bind their owned component's props to some value the owner has computed based on its `props` or `state`. Since this process happens recursively, data changes are automatically reflected everywhere they are used.
When you create a React component instance, you can include additional React components or JavaScript expressions between the opening and closing tags like this:
## A note on performance
```javascript
<Parent><Child /></Parent>
```
You may be thinking that it's expensive to react to changing data if there are a large number of nodes under an owner. The good news is that JavaScript is fast and `render()` methods tend to be quite simple, so in most applications this is extremely fast. Additionally, the bottleneck is almost always the DOM mutation and not JS execution, and React will optimize this for you using batching and change detection.
`Parent` can read its children by accessing the special `this.props.children` prop.
However, sometimes you really want to have fine-grained control over your performance. In that case, simply override `shouldComponentUpdate()` to return false when you want React to skip processing of a subtree. See [the React API docs](./api.html) for more information.
### Child Reconciliation
**Note:** if `shouldComponentUpdate()` returns false when data has actually changed, React can't keep your UI in sync. Be sure you know what you're doing while using it, and only use this function when you have a noticeable performance problem. Don't underestimate how fast JavaScript is relative to the DOM.
> Reconciliation is the process by which React updates the DOM with each new render pass.
## Build reusable component libraries!
In general, children are reconciled according to the order in which they are rendered. For example, suppose two render passes generate the following respective markup:
When designing interfaces, break down the common design elements (buttons, form fields, layout components, etc) into reusable components with well-defined interfaces. That way, the next time you need to build some UI you can write much less code, which means faster development time, less bugs, and less bytes down the wire.
```html
// Render Pass 1
<Card><p>Paragraph 1</p><p>Paragraph 2</p></Card>
// Render Pass 2
<Card><p>Paragraph 2</p></Card>
```
Intuitively, `<p>Paragraph 1</p>` was removed. Instead, React will reconcile the DOM by changing the text content of the first child and destroying the last child. React reconciles according to the *order* of the children.
## Prop validation
### Stateful Children
As your app grows it's helpful to ensure that your components are used correctly. We do this using `propTypes`.
For most components, this is not a big deal. However, for stateful components that maintain data in `this.state` across render passes, this can be very problematic.
** TODO zpao **
In most cases, this can be sidestepped by hiding elements instead of destroying them:
```html
// Render Pass 1
<Card><p>Paragraph 1</p><p>Paragraph 2</p></Card>
// Render Pass 2
<Card><p style={{display: 'none'}}>Paragraph 1</p><p>Paragraph 2</p></Card>
```
## Mixins
### Dynamic Children
Components are the best way to reuse code in React, but sometimes very different components may share some common functionality. These are sometimes called [cross-cutting concerns](http://en.wikipedia.org/wiki/Cross-cutting_concern). React provides `mixins` to solve this problem.
The situation gets more complicated when the children are shuffled around (as in search results) or if new components are added onto the front of the list (as in streams). In these cases where the identity and state of each child must be maintained across render passes, you can uniquely identify each child by assigning it a `key`:
One common use case is a component wanting to update itself on a time interval. It's easy to use `setInterval()`, but it's important to cancel your interval when you don't need it anymore. React provides [lifecycle methods](./06-working-with-the-browser.html)
```javascript
render: function() {
var results = this.props.results;
return (
<ol>
{this.results.map(function(result) {
return <li key={result.id}>{result.text}</li>;
})}
</ol>
);
}
```
When React reconciles the keyed children, it will ensure that any child with `key` will be reordered (instead of clobbered) or destroyed (instead of reused).
## Data flow
In React, data flows from owner to owned component through `props` as discussed above. This is effectively one-way data binding: owners bind their owned component's props to some value the owner has computed based on its `props` or `state`. Since this process happens recursively, data changes are automatically reflected everywhere they are used.
## A note on performance
You may be thinking that it's expensive to react to changing data if there are a large number of nodes under an owner. The good news is that JavaScript is fast and `render()` methods tend to be quite simple, so in most applications this is extremely fast. Additionally, the bottleneck is almost always the DOM mutation and not JS execution, and React will optimize this for you using batching and change detection.
However, sometimes you really want to have fine-grained control over your performance. In that case, simply override `shouldComponentUpdate()` to return false when you want React to skip processing of a subtree. See [the React API docs](./api.html) for more information.
**Note:** if `shouldComponentUpdate()` returns false when data has actually changed, React can't keep your UI in sync. Be sure you know what you're doing while using it, and only use this function when you have a noticeable performance problem. Don't underestimate how fast JavaScript is relative to the DOM.

86
docs/refactor/05-building-effective-reusable-components.md

@ -0,0 +1,86 @@
## Build reusable component libraries!
When designing interfaces, break down the common design elements (buttons, form fields, layout components, etc) into reusable components with well-defined interfaces. That way, the next time you need to build some UI you can write much less code, which means faster development time, less bugs, and less bytes down the wire.
## Prop validation
As your app grows it's helpful to ensure that your components are used correctly. We do this using `propTypes`.
** TODO zpao **
## Transferring props: a shortcut
A common type of React component is one that extends a basic HTML in a simple way. Often you'll want to copy any HTML attributes passed to your component to the underlying HTML element to save typing. React provides `transferPropsTo()` to do just this.
```javascript
/** @jsx React.DOM */
var CheckLink = React.createClass({
render: function() {
// transferPropsTo() will take any props pased to CheckLink
// and copy them to <a>
return this.transferPropsTo(<a>{'√ '}{this.props.children}</a>);
}
});
React.renderComponent(
<CheckLink href="javascript:alert('Hello, world!');">
Click here!
</CheckLink>,
document.getElementById('example')
);
```
## Mixins
Components are the best way to reuse code in React, but sometimes very different components may share some common functionality. These are sometimes called [cross-cutting concerns](http://en.wikipedia.org/wiki/Cross-cutting_concern). React provides `mixins` to solve this problem.
One common use case is a component wanting to update itself on a time interval. It's easy to use `setInterval()`, but it's important to cancel your interval when you don't need it anymore to save memory. React provides [lifecycle methods](./06-working-with-the-browser.html) that let you know when a component is about to be created or destroyed. Let's create a simple mixin that uses these methods to provide an easy `setInterval()` function that will automatically get cleaned up when your component is destroyed.
```javascript
/** @jsx React.DOM */
var SetIntervalMixin = {
componentWillMount: function() {
this.intervals = [];
},
setInterval: function() {
this.intervals.push(setInterval.apply(null, arguments));
},
componentWillUnmount: function() {
this.intervals.map(clearInterval);
}
};
var TickTock = React.createClass({
mixins: [SetIntervalMixin], // Use the mixin
getInitialState: function() {
return {seconds: 0};
},
componentDidMount: function() {
this.setInterval(this.tick, 1000); // Call a method on the mixin
},
tick: function() {
this.setState({seconds: this.state.seconds + 1});
},
render: function() {
return (
<p>
React has been running for {this.state.seconds} seconds.
</p>
);
}
});
React.renderComponent(
<TickTock />,
document.getElementById('example')
);
```
A nice feature of mixins is that if a component is using multiple mixins and several mixins define the same lifecycle method (i.e. several mixins want to do some cleanup when the component is destroyed), all of the lifecycle methods are guaranteed to be called.
## Testing
**TODO: benjamn**

119
docs/refactor/06-forms.md

@ -0,0 +1,119 @@
# Forms
Form components such as `<input>`, `<textarea>`, and `<option>` differ from other native components because they can be mutated via user interactions. These components provide interfaces that make it easier to manage forms in response to user interactions.
## Interactive Props
Form components support a few props that are affected via user interactions:
- `value`, supported by `<input>` and `<textarea>` components.
- `checked`, supported by `<input>` components of type `checkbox` or `radio`.
- `selected`, supported by `<option>` components.
In HTML, the value of `<textarea>` is set via children. In React, you should use `value` instead.
Form components allow listening for changes by setting a callback to the `onChange` prop. The `onChange` prop works across browsers to fire in response to user interactions when:
- The `value` of `<input>` or `<textarea>` changes.
- The `checked` state of `<input>` changes.
- The `selected` state of `<option>` changes.
Like all DOM events, the `onChange` prop is supported on all native components and can be used to listen to bubbled change events.
## Controlled Components
An `<input>` with `value` set is a *controlled* component. In a controlled `<input>`, the value of the rendered element will always reflect the `value` prop. For example:
```javascript
render: function() {
return <input type="text" value="Hello!" />;
}
```
This will render an input that always has a value of `Hello!`. Any user input will have no effect on the rendered element because React has declared the value to be `Hello!`. If you wanted to update the value in response to user input, you could use the `onChange` event:
```javascript
getInitialState: function() {
return {value: 'Hello!'};
},
render: function() {
var value = this.state.value;
return <input type="text" value={value} onChange={this.handleChange} />;
},
handleChange: function(event) {
this.setState({value: event.target.value});
}
```
In this example, we are simply accepting the newest value provided by the user and updating the `value` prop of the `<input>` component. This pattern makes it easy to implement interfaces that respond to or validate user interactions. For example:
```javascript
handleChange: function(event) {
this.setState({value: event.target.value.substr(0, 140)});
}
```
This would accept user input but truncate the value to the first 140 characters.
## Uncontrolled Components
An `<input>` that does not supply a `value` (or sets it to `null`) is an *uncontrolled* component. In an uncontrolled `<input>`, the value of the rendered element will reflect the user's input. For example:
```javascript
render: function() {
return <input type="text" />;
}
```
This will render an input that starts off with an empty value. Any user input will be immediately reflected by the rendered element. If you wanted to listen to updates to the value, you could use the `onChange` event just like you can with controlled components.
If you want to initialize the component with a non-empty value, you can supply a `defaultValue` prop. For example:
```javascript
render: function() {
return <input type="text" defaultValue="Hello!" />;
}
```
This example will function much like the **Controlled Components** example above.
Likewise, `<input>` supports `defaultChecked` and `<option>` supports `defaultSelected`.
## Advanced Topics
### Why controlled components?
Using form components such as `<input>` in React presents a challenge that is absent when writing traditional form HTML. For example, in HTML:
```html
<input type="text" name="title" value="Untitled" />
```
This renders an input *initialized* with the value, `Untitled`. When the user updates the input, the node's value *property* will change. However, `node.getAttribute('value')` will still return the value used at initialization time, `Untitled`.
Unlike HTML, React components must represent the state of the view at any point in time and not only at initialization time. For example, in React:
```javascript
render: function() {
return <input type="text" name="title" value="Untitled" />;
}
```
Since this method describes the view at any point in time, the value of the text input should *always* be `Untitled`.
### Why textarea value?
In HTML, the value of `<textarea>` is usually set using its children:
```html
<!-- counterexample: DO NOT DO THIS! -->
<textarea name="description">This is the description.</textarea>
```
For HTML, this easily allows developers to supply multiline values. However, since React is JavaScript, we do not have string limitations and can use `\n` if we want newlines. In a world where we have `value` and `defaultValue`, it is ambiguous what role children play. For this reason, you should not use children when setting `<textarea>` values:
```javascript
<textarea name="description" value="This is a description." />
```
If you *do* decide to use children, they will behave like `defaultValue`.

113
docs/refactor/07-working-with-the-browser.md

@ -0,0 +1,113 @@
# Working with the browser
React provides powerful abstractions that free you from touching the DOM directly in most cases, but sometimes you simply need to access the underlying API, perhaps to work with a third-party library.
## The mock DOM
React is so fast because it never talks to the DOM directly. React maintains a fast in-memory representation of the DOM. `render()` methods return a *description* of the DOM, and React can diff this description with the in-memory representation to compute the fastest way to update the browser.
Additionally, React implements a full synthetic event system such that all event objects are guaranteed to conform to the W3C spec despite browser quirks, and everything bubbles consistently and in a performant way cross-browser. You can even use some HTML5 events in IE8!
Most of the time you should stay within React's "faked browser" world since it's more performant and easier to reason about. However, sometimes you simply need to access the underlying API, perhaps to work with a third-party library like a jQuery plugin. React provides escape hatches for you to use the underlying DOM API directly.
## Refs and getDOMNode()
To interact with the browser, you'll need a reference to a DOM node. Every mounted React component has a `getDOMNode()` function which you can call to get a reference to it.
**Warning:** `getDOMNode()` only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling `getDOMNode()` in `render()` on a component that has yet to be created) an exception will be thrown.
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 refs to refer to a component you own. They work like this:
```javascript
/** @jsx React.DOM */
var MyComponent = React.createClass({
handleClick: function() {
// Explicitly focus the text input using the raw DOM API.
this.refs.myTextInput.getDOMNode().focus();
},
render: function() {
// The ref attribute adds a reference to the component to
// this.refs when the component is mounted.
return (
<div>
<input type="text" ref="myTextInput" />
<input
type="button"
value="Focus the text input"
onClick={this.handleClick}
/>
</div>
);
}
});
React.renderComponent(
<MyComponent />,
document.getElementById('example')
);
```
## More about refs
To learn more about refs, including ways to use them effectively, see our [more about refs](./07.1-more-about-refs.md) documentation.
## Component lifecycle
Components have three main parts of their lifecycle:
- **Mounting:** A component is being inserted into the DOM.
- **Updating:** A component is being re-rendered to determine if the DOM should be updated.
- **Unmounting:** A component is being removed from the DOM.
React provides lifecycle methods that you can override to hook into this process. We provide **will** methods, which are called right before something happens, and **did** methods which are called right after something happens.
### Mounting
- `getInitialState(): object` is invoked before a component is mounted. Stateful components should implement this and return the initial state data.
- `componentWillMount()` is invoked immediately before mounting occurs.
- `componentDidMount(DOMElement rootNode)` is invoked immediately after mounting occurs. Initialization that requires DOM nodes should go here.
### Updating
- `componentWillReceiveProps(object nextProps)` is invoked when a mounted component receives new props. This method should be used to compare `this.props` and `nextProps` to perform state transitions using `this.setState()`.
- `shouldComponentUpdate(object nextProps, object nextState): boolean` is invoked when a component decides whether any changes warrant an update to the DOM. Implement this as an optimization to compare `this.props` with `nextProps` and `this.state` with `nextState` and return false if React should skip updating.
- `componentWillUpdate(object nextProps, object nextState)` is invoked immediately before updating occurs. You cannot call `this.setState()` here.
- `componentDidUpdate(object prevProps, object prevState, DOMElement rootNode)` is invoked immediately after updating occurs.
### Unmounting
- `componentWillUnmount()` is invoked immediately before a component is unmounted and destroyed. Cleanup should go here.
### Mounted Methods
_Mounted_ composite components also support the following methods:
- `getDOMNode(): DOMElement` can be invoked on any mounted component in order to obtain a reference to its rendered DOM node.
- `forceUpdate()` can be invoked on any mounted component when you know that some deeper aspect of the component's state has changed without using `this.setState()`.
> Note:
>
> The `DOMElement rootNode` argument of `componentDidMount()` and
> `componentDidUpdate()` is a convenience. The same node can be obtained by
> calling `this.getDOMNode()`.
## Browser suppport and polyfills
At Facebook, we support older browsers, including IE8. We've had polyfills in place for a long time to allow us to write forward-thinking JS. This means we don't have a bunch of hacks scattered throughout our codebase and we can still expect our code to "just work". For example, instead of seeing `+new Date()`, we can just write `Date.now()`. Since the open source React is the same as what we use internally, we've carried over this philosophy of using forward thinking JS.
In addition to that philosphy, we've also taken the stance that we, as authors of a JS library, should not be shipping polyfills as a part of our library. If every library did this, there's a good chance you'd be sending down the same polyfill multiple times, which could be a sizable chunk of dead code. If your product needs to support older browsers, chances are you're already using something like [es5-shim](https://github.com/kriskowal/es5-shim).
### Polyfills needed to support older browsers
* `Array.isArray`
* `Array.prototype.forEach`
* `Array.prototype.indexOf`
* `Function.prototype.bind`
* `Date.now`
* `Array.prototype.some` (also in `es5-shim.js`)
All of these can be polyfilled using `es5-shim.js` from https://github.com/kriskowal/es5-shim.
* `console.*` - https://github.com/paulmillr/console-polyfill
* `Object.create` - Provided in `es5-sham.js` @ https://github.com/kriskowal/es5-shim

130
docs/refactor/07.1-more-about.refs.md

@ -0,0 +1,130 @@
# More about refs
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.
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, `''`.
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleKeyUp: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
this.setState({userInput: ''}); // Clear the input
// We wish to focus the <input /> now!
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
Click To Focus and Reset
</div>
<input
value={this.state.userInput}
onKeyUp={this.handleKeyUp}
/>
</div>
);
}
});
```
Notice how, in this example, we want to "tell" the input something - something that it cannot infer from it's props over time. In this case we want to "tell" it that it should now become focused. However, there are some challenges. What is returned from render is not your actual composition of "child" components, it is merely a *description* of the children at a particular instance in time - a snapshot, if you will.
NOTE: 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.
This means that you should never "hold onto" something that you return from `render()` and then expect it to be anything meaningful.
```javascript
// counterexample: DO NOT DO THIS!
render: function() {
var myInput = <input />; // I'm going to try to call methods on this
this.rememberThisInput = myInput; // input at some point in the future! YAY!
return (
<div>
<div>...</div>
{myInput}
</div>
);
}
```
In this counterexample, the `<input />` is merely a *description* of an `<input />`. This description is used to create a *real* **backing instance** for the `<input />`.
So how do we talk to the *real* backing instance of the input?
## The `ref` attribute
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.
It's as simple as:
1. Assign a `ref` attribute to anything returned from `render` such as:
```html
<input ref="myInput" />
```
2. In some other code (typically event handler code), access the **backing instance** via `this.refs` as in:
```javascript
this.refs.myInput
```
## Completing the Example
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleKeyUp: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
this.setState({userInput: ''}); // Clear the input
this.refs.theInput.getDOMNode().focus(); // Boom! Focused!
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
Click To Focus and Reset
</div>
<input
ref="theInput"
value={this.state.userInput}
onKeyUp={this.handleKeyUp}
/>
</div>
);
}
});
```
In this example, our render function returns a description of an <input /> instance. But the true instance is accessed via `this.refs.theInput`. As long as a child component with `ref="theInput"` is returned from render, `this.refs.theInput` will access the the proper instance. This even works on higher level (non-DOM) components such as <Typeahead ref="myTypeahead" />.
## Summary
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.
**Benefits**:
- You can define any public method on your component classes (such as a reset method on a Typeahead) and call those public methods through refs (such as this.refs.myTypeahead.reset()).
- Performing DOM measurements almost always requires reaching out to a "native" component such as <input /> and accessing its underlying DOM node via this.refs.myInput.getDOMNode(). Refs are one of the only practical ways of doing this reliably.
Refs are automatically book-kept for you! If that child is destroyed, its ref is also destroyed for you. No worrying about memory here (unless you do something crazy to retain a reference yourself).
**Cautions**:
- **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.
- 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"`.
- 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.
Loading…
Cancel
Save