Browse Source

Merge pull request #5711 from iamchenxin/docs122215

[docs] Update zh-docs with 7e2a7f0
main
Paul O’Shannessy 9 years ago
parent
commit
e454bb23ed
  1. 10
      docs/02-displaying-data.zh-CN.md
  2. 8
      docs/02.1-jsx-in-depth.md
  3. 3
      docs/02.1-jsx-in-depth.zh-CN.md
  4. 5
      docs/02.2-jsx-spread.zh-CN.md
  5. 7
      docs/02.3-jsx-gotchas.zh-CN.md
  6. 9
      docs/03-interactivity-and-dynamic-uis.zh-CN.md
  7. 6
      docs/04-multiple-components.zh-CN.md
  8. 3
      docs/05-reusable-components.md
  9. 85
      docs/05-reusable-components.zh-CN.md
  10. 9
      docs/06-transferring-props.zh-CN.md
  11. 8
      docs/07-forms.zh-CN.md
  12. 59
      docs/08-working-with-the-browser.zh-CN.md
  13. 174
      docs/08.1-more-about-ref-zh-CN.md
  14. 183
      docs/08.1-more-about-refs.zh-CN.md
  15. 16
      docs/09-tooling-integration.zh-CN.md
  16. 7
      docs/10-addons.zh-CN.md
  17. 15
      docs/10.1-animation.zh-CN.md

10
docs/02-displaying-data.zh-CN.md

@ -1,7 +1,6 @@
---
id: displaying-data-zh-CN
title: 显示数据
layout: docs
permalink: displaying-data-zh-CN.html
prev: why-react-zh-CN.html
next: jsx-in-depth-zh-CN.html
@ -9,7 +8,6 @@ next: jsx-in-depth-zh-CN.html
用户界面能做的最基础的事就是显示一些数据。React 让显示数据变得简单,当数据变化的时候,用户界面会自动同步更新。
## 开始
让我们看一个非常简单的例子。新建一个名为 `hello-react.html` 的文件,代码内容如下:
@ -57,7 +55,6 @@ setInterval(function() {
}, 500);
```
## 被动更新 (Reactive Updates)
在浏览器中打开 `hello-react.html` ,在输入框输入你的名字。你会发现 React 在用户界面中只改变了时间, 任何你在输入框输入的内容一直保留着,即使你没有写任何代码来完成这个功能。React 为你解决了这个问题,做了正确的事。
@ -66,7 +63,6 @@ setInterval(function() {
对这个组件的输入称为 `props` - "properties"的缩写。得益于 JSX 语法,它们通过参数传递。你必须知道在组件里,这些属性是不可改变的,也就是说 **`this.props` 是只读的**。
## 组件就像是函数
React 组件非常简单。你可以认为它们就是简单的函数,接受 `props``state` (后面会讨论) 作为参数,然后渲染出 HTML。正是应为它们是这么的简单,这使得它们非常容易理解。
@ -75,12 +71,13 @@ React 组件非常简单。你可以认为它们就是简单的函数,接受 `
>
> **只有一个限制**: React 组件只能渲染单个根节点。如果你想要返回多个节点,它们*必须*被包含在同一个节点里。
## JSX 语法
我们坚信组件是正确方法去做关注分离,而不是通过“模板”和“展示逻辑”。我们认为标签和生成它的代码是紧密相连的。此外,展示逻辑通常是很复杂的,通过模板语言实现这些逻辑会产生大量代码。
我们得出解决这个问题最好的方案是通过 JavaScript 直接生成模板,这样你就可以用一个真正语言的所有表达能力去构建用户界面。为了使这变得更简单,我们做了一个非常简单、**可选**类似 HTML 语法 ,通过函数调用即可生成模板的编译器,称为 JSX。
我们得出解决这个问题最好的方案是通过 JavaScript 直接生成模板,这样你就可以用一个真正语言的所有表达能力去构建用户界面。
为了使这变得更简单,我们做了一个非常简单、**可选**类似 HTML 语法 ,通过函数调用即可生成模板的编译器,称为 JSX。
**JSX 让你可以用 HTML 语法去写 JavaScript 函数调用** 为了在 React 生成一个链接,通过纯 JavaScript 你可以这么写:
@ -125,4 +122,3 @@ var root = React.DOM.ul({ className: 'my-list' },
React.DOM.li(null, 'Text Content')
);
```

8
docs/02.1-jsx-in-depth.md

@ -82,10 +82,7 @@ var Nav = React.createClass({ });
var Nav = React.createClass({displayName: "Nav", });
```
Use the [Babel REPL](https://babeljs.io/repl/) to try out JSX and see how it
desugars into native JavaScript, and the
[HTML to JSX converter](/react/html-jsx.html) to convert your existing HTML to
JSX.
Use the [Babel REPL](https://babeljs.io/repl/) to try out JSX and see how it desugars into native JavaScript, and the [HTML to JSX converter](/react/html-jsx.html) to convert your existing HTML to JSX.
If you want to use JSX, the [Getting Started](/react/docs/getting-started.html) guide shows how to set up compilation.
@ -163,8 +160,7 @@ var App = (
### Attribute Expressions
To use a JavaScript expression as an attribute value, wrap the expression in a
pair of curly braces (`{}`) instead of quotes (`""`).
To use a JavaScript expression as an attribute value, wrap the expression in a pair of curly braces (`{}`) instead of quotes (`""`).
```javascript
// Input (JSX):

3
docs/02.1-jsx-in-depth.zh-CN.md

@ -8,7 +8,6 @@ next: jsx-spread-zh-CN.html
[JSX](https://facebook.github.io/jsx/) 是一个看起来很像 XML 的 JavaScript 语法扩展。React 可以用来做简单的 JSX 句法转换。
## 为什么要用 JSX?
你不需要为了 React 使用 JSX,可以直接使用原生 JS。但是,我们建议使用 JSX 是因为它能精确,也是常用的定义包含属性的树状结构的语法。
@ -46,7 +45,6 @@ React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标
> 由于 JSX 就是 JavaScript,一些标识符像 `class``for` 不建议作为 XML
> 属性名。作为替代,React DOM 使用 `className``htmlFor` 来做对应的属性。
## 转换(Transform)
JSX 把类 XML 的语法转成原生 JavaScript,XML 元素、属性和子节点被转换成 `React.createElement` 的参数。
@ -90,6 +88,7 @@ var Nav = React.createClass({displayName: "Nav", });
> 注意:
>
>
> JSX 表达式总是会当作 ReactElement 执行。具体的实际细节可能不同。一种优化
> 的模式是把 ReactElement 当作一个行内的对象字面量形式来绕过
> `React.createElement` 里的校验代码。

5
docs/02.2-jsx-spread.zh-CN.md

@ -12,7 +12,6 @@ next: jsx-gotchas-zh-CN.html
var component = <Component foo={x} bar={y} />;
```
## 修改 Props 是不好的,明白吗
如果你不知道要设置哪些 Props,那么现在最好不要设置它:
@ -27,7 +26,6 @@ next: jsx-gotchas-zh-CN.html
Props 应该被认为是不可变的。在别处修改 props 对象可能会导致预料之外的结果,所以原则上这将是一个冻结的对象。
## 展开属性(Spread Attributes)
现在你可以使用 JSX 的新特性 - 展开属性:
@ -49,7 +47,6 @@ Props 应该被认为是不可变的。在别处修改 props 对象可能会导
console.log(component.props.foo); // 'override'
```
## 这个奇怪的 `...` 标记是什么?
这个 `...` 操作符(增强的操作符)已经被 [ES6 数组](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) 支持。相关的还有 ES7 规范草案中的 [Object 剩余和展开属性(Rest and Spread Properties)](https://github.com/sebmarkbage/ecmascript-rest-spread)。我们利用了这些还在制定中标准中已经被支持的特性来使 JSX 拥有更优雅的语法。
这个 `...` 操作符(增强的操作符)已经被 [ES6 数组](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) 支持。相关的还有 ECMAScript 规范草案中的 [Object 剩余和展开属性(Rest and Spread Properties)](https://github.com/sebmarkbage/ecmascript-rest-spread)。我们利用了这些还在制定中标准中已经被支持的特性来使 JSX 拥有更优雅的语法。

7
docs/02.3-jsx-gotchas.zh-CN.md

@ -52,6 +52,7 @@ HTML 实体可以插入到 JSX 的文本中。
<div dangerouslySetInnerHTML={{'{{'}}__html: 'First &middot; Second'}} />
```
## 自定义 HTML 属性
如果往原生 HTML 元素里传入 HTML 规范里不存在的属性,React 不会显示它们。如果需要使用自定义属性,要加 `data-` 前缀。
@ -60,6 +61,12 @@ HTML 实体可以插入到 JSX 的文本中。
<div data-custom-attribute="foo" />
```
然而,在自定义元素中任意的属性都是被支持的 (那些在tag名里带有连接符或者 `is="..."` 属性的)
```javascript
<x-my-component custom-attribute="foo" />
```
`aria-` 开头的 [网络无障碍](http://www.w3.org/WAI/intro/aria) 属性可以正常使用。
```javascript

9
docs/03-interactivity-and-dynamic-uis.zh-CN.md

@ -8,7 +8,6 @@ next: multiple-components-zh-CN.html
我们已经学习如何使用 React [显示数据](/react/docs/displaying-data-zh-CN.html)。现在让我们来学习如何创建交互式界面。
## 简单例子
```javascript
@ -35,7 +34,6 @@ ReactDOM.render(
);
```
## 事件处理与合成事件(Synthetic Events)
React 里只需把事件处理器(event handler)以骆峰命名(camelCased)形式当作组件的 props 传入即可,就像使用普通 HTML 那样。React 内部创建一套合成事件系统来使所有事件在 IE8 和以上浏览器表现一致。也就是说,React 知道如何冒泡和捕获事件,而且你的事件处理器接收到的 events 参数与 [W3C 规范](http://www.w3.org/TR/DOM-Level-3-Events/) 一致,无论你使用哪种浏览器。
@ -48,19 +46,16 @@ React 里只需把事件处理器(event handler)以骆峰命名(camelCased
**事件代理 :** React 实际并没有把事件处理器绑定到节点本身。当 React 启动的时候,它在最外层使用唯一一个事件监听器处理所有事件。当组件被加载和卸载时,只是在内部映射里添加或删除事件处理器。当事件触发,React 根据映射来决定如何分发。当映射里处理器时,会当作空操作处理。参考 [David Walsh 很棒的文章](http://davidwalsh.name/event-delegate) 了解这样做高效的原因。
## 组件其实是状态机(State Machines)
React 把用户界面当作简单状态机。把用户界面想像成拥有不同状态然后渲染这些状态,可以轻松让用户界面和数据保持一致。
React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。React 来决定如何最高效地更新 DOM。
## State 工作原理
常用的通知 React 数据变化的方法是调用 `setState(data, callback)`。这个方法会合并(merge) `data``this.state`,并重新渲染组件。渲染完成后,调用可选的 `callback` 回调。大部分情况下不需要提供 `callback`,因为 React 会负责把界面更新到最新状态。
## 哪些组件应该有 State?
大部分组件的工作应该是从 `props` 里取数据并渲染出来。但是,有时需要对用户输入、服务器请求或者时间变化等作出响应,这时才需要使用 State。
@ -69,16 +64,14 @@ React 里,只需更新组件的 state,然后根据新的 state 重新渲染
常用的模式是创建多个只负责渲染数据的无状态(stateless)组件,在它们的上层创建一个有状态(stateful)组件并把它的状态通过 `props` 传给子级。这个有状态的组件封装了所有用户的交互逻辑,而这些无状态组件则负责声明式地渲染数据。
## 哪些 *应该* 作为 State?
**State 应该包括那些可能被组件的事件处理器改变并触发用户界面更新的数据。** 真实的应用中这种数据一般都很小且能被 JSON 序列化。当创建一个状态化的组件时,想象一下表示它的状态最少需要哪些数据,并只把这些数据存入 `this.state`。在 `render()` 里再根据 state 来计算你需要的其它数据。你会发现以这种方式思考和开发程序最终往往是正确的,因为如果在 state 里添加冗余数据或计算所得数据,需要你经常手动保持数据同步,不能让 React 来帮你处理。
## 哪些 *不应该* 作为 State?
`this.state` 应该仅包括能表示用户界面状态所需的最少数据。因些,它不应该包括:
* **计算所得数据:** 不要担心根据 state 来预先计算数据 —— 把所有的计算都放到 `render()` 里更容易保证用户界面和数据的一致性。例如,在 state 里有一个数组(listItems),我们要把数组长度渲染成字符串, 直接在 `render()` 里使用 `this.state.listItems.length + ' list items'` 比把它放到 state 里好的多。
* **React 组件:**`render()` 里使用当前 props 和 state 来创建它。
* **基于 props 的重复数据:** 尽可能使用 props 来作为惟一数据来源。把 props 保存到 state 的一个有效的场景是需要知道它以前值的时候,因为未来的 props 可能会变化。
* **基于 props 的重复数据:** 尽可能使用 props 来作为实际状态的源。把 props 保存到 state 的一个有效的场景是需要知道它以前值的时候,因为 props 可能因为父组件重绘的结果而变化。

6
docs/04-multiple-components.zh-CN.md

@ -8,7 +8,6 @@ next: reusable-components-zh-CN.html
目前为止,我们已经学了如何用单个组件来展示数据和处理用户输入。下一步让我们来体验 React 最激动人心的特性之一:可组合性(composability)。
## 动机:关注分离
通过复用那些接口定义良好的组件来开发新的模块化组件,我们得到了与使用函数和类相似的好处。具体来说就是能够通过开发简单的组件把程序的*不同关注面分离*。如果为程序开发一套自定义的组件库,那么就能以最适合业务场景的方式来展示你的用户界面。
@ -53,15 +52,12 @@ ReactDOM.render(
);
```
## 从属关系
上面例子中,`Avatar` 拥有 `ProfilePic``ProfileLink` 的实例。`拥有者` 就是给其它组件设置 `props` 的那个组件。更正式地说,
如果组件 `Y``render()` 方法是创建了组件 `X`,那么 `Y` 就拥有 `X`。上面讲过,组件不能修改自身的 `props` - 它们总是与它们拥有者设置的保持一致。这是保持用户界面一致性的基本不变量。
上面例子中,`Avatar` 拥有 `ProfilePic``ProfileLink` 的实例。`拥有者` 就是给其它组件设置 `props` 的那个组件。更正式地说,如果组件 `Y``render()` 方法是创建了组件 `X`,那么 `Y` 就拥有 `X`。上面讲过,组件不能修改自身的 `props` - 它们总是与它们拥有者设置的保持一致。这是保持用户界面一致性的基本不变量。
把从属关系与父子关系加以区别至关重要。从属关系是 React 特有的,而父子关系简单来讲就是DOM 里的标签的关系。在上一个例子中,`Avatar` 拥有 `div`、`ProfilePic` 和 `ProfileLink` 实例,`div` 是 `ProfilePic``ProfileLink` 实例的**父级**(但不是拥有者)。
## 子级
实例化 React 组件时,你可以在开始标签和结束标签之间引用在React 组件或者Javascript 表达式:

3
docs/05-reusable-components.md

@ -80,8 +80,7 @@ React.createClass({
### Single Child
With `React.PropTypes.element` you can specify that only a single child can be passed to
a component as children.
With `React.PropTypes.element` you can specify that only a single child can be passed to a component as children.
```javascript
var MyComponent = React.createClass({

85
docs/05-reusable-components.zh-CN.md

@ -8,7 +8,6 @@ next: transferring-props-zh-CN.html
设计接口的时候,把通用的设计元素(按钮,表单框,布局组件等)拆成接口良好定义的可复用的组件。这样,下次开发相同界面程序时就可以写更少的代码,也意义着更高的开发效率,更少的 Bug 和更少的程序体积。
## Prop 验证
随着应用不断变大,保证组件被正确使用变得非常有用。为此我们引入 `propTypes`。`React.PropTypes` 提供很多验证器 (validator) 来验证传入数据的有效性。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。注意为了性能考虑,只在开发环境验证 `propTypes`。下面用例子来说明不同验证器的区别:
@ -32,10 +31,12 @@ React.createClass({
// React 元素
optionalElement: React.PropTypes.element,
// 你同样可以断言一个 prop 是一个类的实例。
// 用 JS 的 instanceof 操作符声明 prop 为类的实例。
optionalMessage: React.PropTypes.instanceOf(Message),
// 用 enum 来限制 prop 只接受指定的值。
// 你可以用 enum 的方式
// 确保你的 prop 被限定为指定值。
optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),
// 指定的多个对象类型中的一个
@ -57,14 +58,16 @@ React.createClass({
fontSize: React.PropTypes.number
}),
// 以后任意类型加上 `isRequired` 来使 prop 不可空。
// 你可以在任意东西后面加上 `isRequired`
// 来确保 如果 prop 没有提供 就会显示一个警告。
requiredFunc: React.PropTypes.func.isRequired,
// 不可空的任意类型
requiredAny: React.PropTypes.any.isRequired,
// 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接
// 使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。
// 你可以自定义一个验证器。如果验证失败需要返回一个 Error 对象。
// 不要直接使用 `console.warn` 或抛异常,
// 因为这在 `oneOfType` 里不起作用。
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
@ -75,6 +78,26 @@ React.createClass({
});
```
### Single Child
`React.PropTypes.element` 你可以指定仅有一个子级能被传送给组件
```javascript
var MyComponent = React.createClass({
propTypes: {
children: React.PropTypes.element.isRequired
},
render: function() {
return (
<div>
{this.props.children} // 这里必须是一个元素否则就会警告
</div>
);
}
});
```
## 默认 Prop 值
@ -93,9 +116,9 @@ var ComponentWithDefaultProps = React.createClass({
当父级没有传入 props 时,`getDefaultProps()` 可以保证 `this.props.value` 有默认值,注意 `getDefaultProps` 的结果会被 *缓存*。得益于此,你可以直接使用 props,而不必写手动编写一些重复或无意义的代码。
## 传递 Props:小技巧
## 传递 Props:捷径
有一些常用的 React 组件只是对 HTML 做简单扩展。通常,你想少写点代码来把传入组件的 props 复制到对应的 HTML 元素上。这时 JSX 的 _spread_ 语法会帮到你
有一些常用的 React 组件只是对 HTML 做简单扩展。通常,你想 复制任何传进你的组件的HTML属性 到底层的HTML元素上。为了减少输入,你可以用 JSX _spread_ 语法来完成
```javascript
var CheckLink = React.createClass({
@ -113,28 +136,6 @@ ReactDOM.render(
);
```
## 单个子级
`React.PropTypes.element` 可以限定只能有一个子级传入。
```javascript
var MyComponent = React.createClass({
propTypes: {
children: React.PropTypes.element.isRequired
},
render: function() {
return (
<div>
{this.props.children} // 有且仅有一个元素,否则会抛异常。
</div>
);
}
});
```
## Mixins
组件是 React 里复用代码最佳方式,但是有时一些复杂的组件间也需要共用一些功能。有时会被称为 [跨切面关注点](https://en.wikipedia.org/wiki/Cross-cutting_concern)。React 使用 `mixins` 来解决这类问题。
@ -228,3 +229,29 @@ Counter.defaultProps = { initialCount: 0 };
不幸的是ES6的发布没有任何mixin的支持。因此,当你在ES6 classes下使用React时不支持mixins。作为替代,我们正在努力使它更容易支持这些用例不依靠mixins。
## 无状态函数
你也可以用 JavaScript 函数来定义你的 React 类。例如使用无状态函数语法:
```javascript
function HelloMessage(props) {
return <div>Hello {props.name}</div>;
}
ReactDOM.render(<HelloMessage name="Sebastian" />, mountNode);
```
或者使用新的ES6箭头函数:
```javascript
var HelloMessage = (props) => <div>Hello {props.name}</div>;
ReactDOM.render(<HelloMessage name="Sebastian" />, mountNode);
```
这个简化的组件API旨在用于那些纯函数态的组件 。这些组件必须没有保持任何内部状态,没有备份实例,也没有组件生命周期方法。他们纯粹的函数式的转化他们的输入,没有引用。
然而,你仍然可以以设置为函数的properties的方式来指定 `.propTypes``.defaultProps`,就像你在ES6类里设置他们那样。
> 注意:
>
> 因为无状态函数没有备份实例,你不能附加一个引用到一个无状态函数组件。 通常这不是问题,因为无状态函数不提供一个命令式的API。没有命令式的API,你就没有任何需要实例来做的事。然而,如果用户想查找无状态函数组件的DOM节点,他们必须把这个组件包装在一个有状态组件里(比如,ES6 类组件) 并且连接一个引用到有状态的包装组件。
在理想世界里,你的大多数组件都应该是无状态函数式的,因为这些无状态组件可以在React核心里经过一个快速的代码路径。 如果可能,这是推荐的模式。

9
docs/06-transferring-props.zh-CN.md

@ -20,7 +20,7 @@ React 里有一个非常常用的模式就是对组件做一层抽象。组件
React.createElement(Component, Object.assign({}, this.props, { more: 'values' }));
```
下面的教程介绍一些最佳实践。使用了 JSX 和 ES7 的还在试验阶段的特性
下面的教程介绍一些最佳实践。使用了 JSX 和 试验性的ECMAScript 语法
## 手动传递
@ -100,7 +100,6 @@ var FancyCheckbox = React.createClass({
});
```
## 使用和传递同一个 Prop
如果组件需要使用一个属性又要往下传递,可以直接使用 `checked={checked}` 再传一次。这样做比传整个 `this.props` 对象要好,因为更利于重构和语法检查。
@ -129,12 +128,11 @@ var FancyCheckbox = React.createClass({
>
> 顺序很重要,把 `{...other}` 放到 JSX props 前面会使它不被覆盖。上面例子中我们可以保证 input 的 type 是 `"checkbox"`
## 剩余属性和展开属性 `...`
剩余属性可以把对象剩下的属性提取到一个新的对象。会把所有在解构赋值中列出的属性剔除。
这是 [ES7 草案](https://github.com/sebmarkbage/ecmascript-rest-spread) 中的试验特性。
这是 [ECMAScript 草案](https://github.com/sebmarkbage/ecmascript-rest-spread) 中的试验特性。
```javascript
var { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
@ -145,8 +143,7 @@ z; // { a: 3, b: 4 }
> 注意:
>
> 使用 [JSX 命令行工具](https://www.npmjs.com/package/react-tools) 配合 `--harmony` 标记来启用 ES7 语法。
> 要用 Babel 6转换 rest 和 spread 属性,你需要安装 [`es2015`](https://babeljs.io/docs/plugins/preset-es2015/) preset,[`transform-object-rest-spread`](https://babeljs.io/docs/plugins/transform-object-rest-spread/) 插件并在 `.babelrc` 里配置他们.
## 使用 Underscore 来传递

8
docs/07-forms.zh-CN.md

@ -32,7 +32,6 @@ next: working-with-the-browser-zh-CN.html
>
> 对于 `<input>` and `<textarea>``onChange` 替代 — 一般应该用来替代 — the DOM's 内建的 [`oninput`](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/oninput) 事件处理。
## 受限组件
设置了 `value``<input>` 是一个*受限*组件。 对于受限的 `<input>`,渲染出来的 HTML 元素始终保持 `value` 属性的值。例如:
@ -72,7 +71,6 @@ next: working-with-the-browser-zh-CN.html
当心,在力图标准化复选框与单选按钮的变换处理中,React使用`click` 事件代替 `change` 事件。在大多数情况下它们表现的如同预期,除了在`change` handler中调用`preventDefault` 。`preventDefault` 阻止了浏览器视觉上更新输入,即使`checked`被触发。变通的方式是要么移除`preventDefault`的调用,要么把`checked` 的触发放在一个`setTimeout`里。
## 不受限组件
没有设置 `value`(或者设为 `null`) 的 `<input>` 组件是一个*不受限*组件。对于不受限的 `<input>` 组件,渲染出来的元素直接反应用户输入。例如:
@ -95,7 +93,7 @@ next: working-with-the-browser-zh-CN.html
}
```
这个例子会像上面的**Controlled Components** 例子一样运行。
这个例子会像上面的 **不受限组件** 例子一样运行。
同样的, `<input>` 支持 `defaultChecked``<select>` 支持 `defaultValue`.
@ -103,10 +101,8 @@ next: working-with-the-browser-zh-CN.html
>
> `defaultValue``defaultChecked` props 只能在内部渲染时被使用。 如果你需要在随后的渲染更新值, 你需要使用 [受限组件](#受限组件).
## 高级主题
### 为什么使用受限组件?
在 React 中使用诸如 `<input>` 的表单组件时,遇到了一个在传统 HTML 中没有的挑战。比如下面的代码:
@ -127,7 +123,6 @@ next: working-with-the-browser-zh-CN.html
该方法在任何时间点渲染组件以后,输入框的值就应该 *始终*`Untitled`
### 为什么 `<textarea>` 使用 `value` 属性?
在 HTML 中, `<textarea>` 的值通常使用子节点设置:
@ -145,7 +140,6 @@ next: working-with-the-browser-zh-CN.html
如果 *非要* 使用子节点,效果和使用 `defaultValue` 一样。
### 为什么 `<select>` 使用 `value` 属性
HTML 中 `<select>` 通常使用 `<option>``selected` 属性设置选中状态;React 为了更方面的控制组件,采用以下方式代替:

59
docs/08-working-with-the-browser.zh-CN.md

@ -8,59 +8,17 @@ next: more-about-refs-zh-CN.html
React提供了强大的抽象机制使你在大多数情况下免于直接接触DOM,但有时你仅仅只需要访问底层API,也许是为了与第三方库或者已有的代码协作。
## 虚拟DOM
React如此快速是因为它从不直接操作DOM。React维持了一个快速的内存中的DOM表示。`render()` 方法返回一个DOM的*描述*,然后React能根据内存中的描述diff此描述来计算出最快速的方法更新浏览器。
React非常快速是因为它从不直接操作DOM。React维持了一个快速的内存中的DOM表示。`render()` 方法实际上返回一个对DOM的*描述*,然后React能根据内存中的“描述”来比较此“描述”以计算出最快速的方法更新浏览器。
此外,React实现了一个完备的合成事件(synthetic event)系统,以使得所有的事件对象都被保证符合W3C细则,而不论各个浏览器的怪癖,并且所有事件跨浏览器地一致并高效的冒泡(bubbles),你甚至能在IE8里使用一些HTML5事件!
大多数时间你应该和React的"伪造浏览器"呆在一起,因为它更高性能并且容易推理。然而,有时你只需要访问底层API,或许是为了与第三方库比如一个jQuery插件协作。React为你提供了安全仓口来直接使用底层API。
## Refs 和 findDOMNode()
为了与浏览器互动,你需要一个指向DOM node的引用。React有一个函数`ReactDOM.findDOMNode(component)` ,你能调用以得到一个指向指向组件的DOM node的引用。
> 注意:
>
> `findDOMNode()` 只作用于已挂载的组件(即,已经放置于DOM中的组件)。如果你尝试在还没有被挂载的组件上调用此函数(比如在`render()` 里有待被创建的组件上调用`findDOMNode()`将会抛出一个异常)
为了获得一个指向React组件的引用,你可以要么使用`this` 来得到当前React组件,要么使用refs来引用你拥有的组件。它们像这样工作:
```javascript
var MyComponent = React.createClass({
handleClick: function() {
// 明确的强制text input使用原生DOM API。
ReactDOM.findDOMNode(this.refs.myTextInput).focus();
},
render: function() {
// 当组件被挂载时
// ref属性给this.refs添加了一个指向指向组件的引用
return (
<div>
<input type="text" ref="myTextInput" />
<input
type="button"
value="Focus the text input"
onClick={this.handleClick}
/>
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);
```
## 更多关于Refs
要学习更多有关refs,包括更有效使用它们的方法,请参见[more about refs](/react/docs/more-about-refs.html) 文档。
为了与浏览器互动,你需要一个指向DOM node的引用。你可以连接一个 `ref` 到任何的元素,这允许你引用 组件的 **backing instance** 。它很有用,如果你需要在组件上调用命令式函数,或者想访问底层的DOM节点。要了解很多关于 refs,包括更有效使用他们的方法,请查看我们的 [关于Refs的更多内容](/react/docs/more-about-refs-zh-CN.html) 文档。
## 组件的生命周期
@ -72,14 +30,12 @@ ReactDOM.render(
React提供生命周期方法,以便你可以指定钩挂到这个过程上。我们提供了 **will** 方法,该方法在某事发生前被调用,**did**方法,在某事发生后被调用。
### 挂载
* `getInitialState(): object` 在组件挂载前被调用. 有状态组件(Stateful components) 应该实现此函数并返回初始state的数据。
* `componentWillMount()` 在挂载发生前被立即调用。
* `componentDidMount()` 在挂载发生后被立即调用。 需要DOM node的初始化应该放在这里。
### 更新
* `componentWillReceiveProps(object nextProps)` 当挂载的组件接收到新的props时被调用。此方法应该被用于比较`this.props` 和 `nextProps`以用于使用`this.setState()`执行状态转换。
@ -87,19 +43,15 @@ React提供生命周期方法,以便你可以指定钩挂到这个过程上。
* `componentWillUpdate(object nextProps, object nextState)` 在更新发生前被立即调用。你不能在此调用`this.setState()`。
* `componentDidUpdate(object prevProps, object prevState)` 在更新发生后被立即调用。
### 卸载
* `componentWillUnmount()` 在组件被卸载和摧毁后被立即调用。清理应该放在这里。
### Mounted Methods
### 已挂载的方法
_Mounted_ 复合组件同样支持以下方法:
* `findDOMNode(): DOMElement` 能够在任何已挂载的组件上调用以便于获取指向它渲染的DOM node的引用。
* `forceUpdate()` 能在任何已挂载的组件上调用,当你知道一些更深层次的组件状态变化了但没有使用 `this.setState()`
* `component.forceUpdate()` 可以在任何已挂载的组件上调用,在你知道 某些深处的组件状态被未使用 `this.setState()` 改变了时。
## 浏览器支持和填充物(polyfills)
@ -107,7 +59,6 @@ _Mounted_ 复合组件同样支持以下方法:
除了这种哲学外,我们也采用了这样的立场,我们,作为一个JS库的作者,不应该把polyfills作为我们库的一部分。如果所有的库这样做,就有很大的机会发送同样的polyfill多次,这可能是一个相当大的无用代码。如果你的产品需要支援老的浏览器,你很有可能已经在使用某些东西比如[es5-shim](https://github.com/es-shims/es5-shim)。
### 需要用来支持旧浏览器的Polyfills
来自 [kriskowal's es5-shim](https://github.com/es-shims/es5-shim)的`es5-shim.js` 提供了如下React需要的东西:
@ -134,12 +85,10 @@ _Mounted_ 复合组件同样支持以下方法:
当在IE8里使用HTML5元素,包括`<section>`, `<article>`, `<nav>`, `<header>`, 和 `<footer>`, 同样必须包含[html5shiv](https://github.com/aFarkas/html5shiv) 或者类似的脚本。
### 跨浏览器问题
尽管React在抽象浏览器不同时做的相当好,但一些浏览器被限制或者表现出怪异的行为,我们没能找到变通的方案解决。
#### IE8的onScroll事件
在IE8`onScroll` 事件不冒泡,并且IE8没有定义事件捕获阶段handlers的API,意味React这没有办法去监听这些事件。

174
docs/08.1-more-about-ref-zh-CN.md

@ -1,174 +0,0 @@
---
id: more-about-refs
title: Refs 的更多信息
permalink: more-about-refs-zh-CN.html
prev: working-with-the-browser-zh-CN.html
next: tooling-integration-zh-CN.html
---
在从render方法返回你的UI结构之前,你可能想向从`render()` 返回的组件的实例“伸手”并调用其上的方法。通常,做类似这样的事情没必要在你的引用中制造数据流,因为Reactive的数据量确保最近的`props` 被发送到从 `render()` 返回的每个孩子中。然而,有些情况,这样做还是必须的或者有帮助的。
考虑一下情形,元素`<input />` (他存在于你的子层级中),当你更新它的值为一个空的字符串`''` 的时候,你告诉它获得焦点。
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
this.setState({userInput: ''}); //清空输入
// 现在我们希望获取焦点<input />!
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
Click to Focus and Reset
</div>
<input
value={this.state.userInput}
onChange={this.handleChange}
/>
</div>
);
}
});
```
在这个例子中,注意我们是如何想要“告诉” input 一些事情的- 一些不能从它的props得到的东西。在这种情形下,我们想要“告诉”它,它现在也要改获取焦点了。然而,这里有些挑战。从`render()` 中返回的不是你实际组件的“孩子”组件,相反他是这些孩子在特定的时刻的一个*描述* - 一个快照。
> 注意:
>
>记着,从`render()` 中返回的不是你的*实际*渲染地孩子实例。从`render()` 中返回的仅仅是在你的组件的子层次结构中的这些孩子实例一个特定时刻的*描述*。
这意味着你绝不该“拿”从`render()` 中返回的东西去做什么事情并期望有什么意义。
```javascript
// 反模式:不能工作.
render: function() {
var myInput = <input />; // 我打算在这个上调用这个方法
this.rememberThisInput = myInput; // input在未来的某个时间点上!YAY!
return (
<div>
<div>...</div>
{myInput}
</div>
);
}
```
在这个例子中,`<input />` 仅仅是 `<input />` 的一个*描述*。这个描述不能用来为`<input />`创建一个*真实的* **背后的实例**
那么对 input 的*真实的* 背后的实例,该怎么说呢?
## ref 字符串属性
React 假设你可以向任何的从`render()` 中返回的组件附加一个特别的属性。这个特殊的属性允许你引用任何的从`render()` 返回的东西对于有的**背后的实例**。而且保证在任何时间点都是合适的实例。
简单的说就是:
1. 给任何从`render()` 中返回的东西赋一个`ref` 的属性,如下所示:
```html
<input ref="myInput" />
```
2. 在其他的代码中(通常是事件处理代码中),通过 `this.refs` 来访问 **背后的实例** 如下所示:
```javascript
this.refs.myInput
```
通过调用`this.refs.myInput` 你可以直接方法这个组建的DOM。
## ref 回调属性
`ref` 属性可以用一个回调函数来替换一个名字。当这个组件装载好之后立即执行。被引用的组件被作为一个参数传入,这个回调函数可能立即使用这个组件,或保存这个引用,将来再用(或者两者都做)。
使用ES6的箭头函数,为从`render` 中返回的东西添加一个`ref` 属性非常简单:
```html
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
```
```html
render: function() {
return (
<TextInput
ref={function(input) {
if (input != null) {
input.focus();
}
}} />
);
},
```
注意当引用的组件被卸载以及无论何时这个引用改变之后,旧的引用将会被用`null` 作为一个参数来调用。这避免了当实例被存储的情形下- 像第一个例子那样 - 引起的内存泄漏。注意像这个例子中这样,用inline 函数表达式写引用的时候,每次有更新的时候Reac看到的都是不同的函数对象,在引用被组件的实例调用之前,引用被用`null` 调用。
## 完整的例子
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
// 清空input
this.setState({userInput: ''}, function() {
// 当这个组件被再次渲染之后,这个代码执行
this.refs.theInput.focus(); //获取焦点了!
});
},
render: function() {
return (
<div>
<div onClick={this.clearAndFocusInput}>
Click to Focus and Reset
</div>
<input
ref="theInput"
value={this.state.userInput}
onChange={this.handleChange}
/>
</div>
);
}
});
```
在这个例子中,我们的render函数返回了`<input />` 实例的一个描述。但是真的实例通过`this.refs.theInput` 访问。只要`ref="theInput"` 从`render` 中返回了, `this.refs.theInput` 就可以访问合适的实例。这个事件对于高级的(非DOM)的组件,例如`<Typeahead ref="myTypeahead" />` 也适用的。
## 总结
在不方便通过Reactive的 `props` 和`state` 流的方式传递信息的时候,Refs是给一个特殊的子实例发送消息的重要的方法。然而,他们不应该成为你的应用程序的到哪里去的数据流的抽象。对于那些本质上来说非交互的情形来说,默认的,应该使用Reactive数据流而少用`ref` 。
### 优点:
- 在你的组件类中你可以定义任意的公开方法(例如在一个Typeahead定义一个reset方法),然后通过refs来调用这些方法(像这样`this.refs.myTypeahead.reset()`)。
- 执行 DOM操作,总是要求诸如`<input />` 这样的一个“原生”组件,并通过`this.refs.myInput` 来访问她的低层的MOD 节点。Refs是可以做成这个事的唯一的实践可行的方法。
- Refs自动管理!如果孩子被销毁了,它的ref也被销毁。在这里不用担心内存(除非你做了一些疯狂的事情来自己保持一个引用)。
### 小心:
- *绝对不要* 在组件的render方法内部- 获 当任何组件的render方法还在调用栈中执行的时候,访问refs 。
- 如果你想要保护Google 闭包编译器崩溃的内力,确保绝不作为访问一个被特别的设置为一个字符串的属性。这就意味着,如果你用`ref="myRefString"` 来定义你的ref的话,你必须使用`this.refs['myRefsString']` 来访问。
- 如果你不是用React做服务器编程的,在你的程序中,你首先的倾向是用refs来“让事情发生“。如果这是正是你的情况的话,花点时间,仔细的想想`state` 在这个组件的结构层次中应在在哪里使用。通常,正确的"拥有" 状态的地方是结构层次的高层。把状态放在那些地方通常可以消除使用`ref` 来”让事情发生” 的渴望 - 相反的,数据流通常能完成你的目标。

183
docs/08.1-more-about-refs.zh-CN.md

@ -1,75 +1,74 @@
---
id: more-about-refs-zh-CN
title: 关于Refs的更多内容
title: 对组件的refs
permalink: more-about-refs-zh-CN.html
prev: working-with-the-browser-zh-CN.html
next: tooling-integration-zh-CN.html
---
从render方法返回你的UI结构以后,你也许发现自己想“接触”并且调用从 `render()`返回的组件实例上的方法。通常,这样做对于让数据流过你的应用并不是必须的,因为Reactive的数据流总是确保最新的`props` 被发送到 `render()`输出的每个子级。然而,有一些情况下它仍旧是必要或者有益的。
在建立你的组件以后,你也许发现你想“接触”并且调用从 `render()`返回的组件实例上的方法。大部分情况下,这是不必要的因为响应式的数据流总是确保最近的 props 被送到每一个从 `render()` 输出的子级。然而,有一些情况下它仍旧是必要或者有益的,所以 React 提供了一个被称为 `refs` 的安全舱口。这些 `refs` (引用) 在你需要时特别有用 如:查找被组件绘制的 DOM 标记(例如,绝对定位它),使用 React 组件在一个大的非React组件里,或者转换你已有的代码库到React
考虑这样一种场景,当你想要告诉一个`<input />` 元素(存在于你的实例的子层级)在你更新他的值为空字符串后获得焦点
让我们来看看怎样取得一个ref,然后深入完整的例子
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: 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}
onChange={this.handleChange}
/>
</div>
);
}
});
## 从 ReactDOM.render 返回的 ref
不要被 你在你的组件(它返回一个虚拟的DOM元素)里定义的 `render()` 迷惑了, [ReactDOM.render()](/react/docs/top-level-api.html#reactdom.render) 会返回一个对你的组件的 **backing instance** 的引用(或者 `null` for [stateless components](/react/docs/reusable-components.html#stateless-functions)).
```js
var myComponent = ReactDOM.render(<MyComponent />, myContainer);
```
记住,不管怎样,JSX不会返回一个组件的实例!它只是一个 **ReactElement**: 一个轻量级的表达,告诉React被挂载的组件应该长什么样。
```js
var myComponentElement = <MyComponent />; // 这只是一个 ReactElement.
注意,在这个例子中,我们想 "告诉" input 一些东西 - 那些最后它不能从他的props推断出来的东西。在这个场景中我们想 "告诉" 它,它应该转为获得焦点。然而,有一些挑战。从`render()` 返回的东西不是你实际的 "子" 组件的组合,而是一个在某刻特定实例的子组件的 *描述* - 一个快照。
// 省略一些代码 ...
var myComponentInstance = ReactDOM.render(myComponentElement, myContainer);
myComponentInstance.doSomething();
```
> 注意:
>
> 记住,从 `render()`返回的东西不是你的 *实际的* 被渲染出的子组件实例。从 `render()` 返回的东西仅仅是一个在特定时间你的组件的子层级中的子实例的 *描述*
> 这只应该用在顶层上。在组件内部,让你的 `props``state` 来处理和子组件的通信,或者使用其他获取ref的方法(string attribute or callbacks)。
## ref Callback 属性
这意味着你万万不要把你从`render()`返回的东西 "抓住不放" 然后期望它变成任何有意义的东西
React支持一种非常特殊的属性,你可以附加到任何的组件上。 `ref` 属性可以是一个回调函数,这个回调函数会在组件被挂载后立即执行。被引用的组件会被作为参数传递,回调函数可以用立即使用这个组件,或者保存引用以后使用(或者二者皆是)
```javascript
// 反面模式: 这行不通.
简单的说就是添加一个 `ref` 属性到任何从 `render` 返回的东西上:
```js
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>
);
<TextInput
ref={function(input) {
if (input != null) {
input.focus();
}
}} />
);
},
```
或者使用ES6的箭头函数:
在这个例子中,`<input />` 仅仅是一个`<input />` 的 *描述*。 这个描述被用于为`<input />`创建一个 *真实的* **支持实例(backing instance)**
```js
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
```
所以我们如何与input的 *真实的*支持实例对话?
当连接一个ref到一个DOM组件如 `<div />`,你取回DOM节点;当连接一个ref到一个复合组件如 `<TextInput />`,你会得到React类的实例。在后一种情况下,你可以调用任何那个组件的类暴露的方法。
## ref String 属性
注意当被引用的组件卸载和每当ref变动,旧的ref将会被以`null`做参数调用。这阻止了在实例被保存的情况下的内存泄露,如第一个例子。注意当像在这里的例子,使用内联函数表达式写refs,React在每次更新都看到不同的函数对象,ref将会被以`null` 立即调用在它被以组件实例调用前。
React支持一种非常特殊的属性,你可以附加到任何从`render()`输出的组件上。这个特殊的属性允许你引用任何从`render()`返回的东西的对应 **支持实例(backing instance)** 。它总是保证是适当的实例,在任何时点上。
## ref String 属性
就是这么简单:
React同样支持使用一个字符串(代替回调函数)在任意组件上作为一个 ref prop,尽管这个方法在这点上主要是遗留物。
1. 赋值`ref`属性为任何从`render` 返回的东西,比如:
@ -80,95 +79,59 @@ React支持一种非常特殊的属性,你可以附加到任何从`render()`
2. 在其他一些代码中(典型的事件处理代码),通过`this.refs`访问 **支持实例(backing instance)**,如:
```javascript
this.refs.myInput
```
你可以直接通过调用`ReactDOM.findDOMNode(this.refs.myInput)` 访问组件的DOM node。
## ref 回调属性
`ref` 属性可以是一个回调函数而不是名字。这个回调函数将会在组件挂载以后立即执行。被引用的组件将被作为参数传递,并且回调函数可以立即使用组件,或者保存引用将来使用(或两者都是)。
通过使用ES6的箭头函数,它像添加一个`ref`属性到任何从`render`返回的东西一样简单。
```html
render: function() {
return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
this._input.focus();
},
```
或者
```html
render: function() {
return (
<TextInput
ref={function(input) {
if (input != null) {
input.focus();
}
}} />
);
},
var input = this.refs.myInput;
var inputValue = input.value;
var inputRect = input.getBoundingClientRect();
```
注意当被引用的组件卸载和每当ref变动,旧的ref将会被以`null`做参数调用。这阻止了在实例被保存的情况下的内存泄露,如第一个例子。注意当像在这里的例子,使用内联函数表达式写refs,React在每次更新都看到不同的函数对象,ref将会被以`null` 立即调用在它被以组件实例调用前。
## 完成的示例
## 完整的示例
为了获取一个React组件的引用,你既可以使用 `this` 来获取当前的React组件,也可以使用一个 ref 来获取一个你拥有的组件的引用。他们像这样工作:
```javascript
var App = React.createClass({
getInitialState: function() {
return {userInput: ''};
},
handleChange: function(e) {
this.setState({userInput: e.target.value});
},
clearAndFocusInput: function() {
// Clear the input
this.setState({userInput: ''}, function() {
// This code executes after the component is re-rendered
ReactDOM.findDOMNode(this.refs.theInput).focus(); // Boom! Focused!
});
var MyComponent = React.createClass({
handleClick: function() {
// Explicitly focus the text input using the raw DOM API.
this.myTextInput.focus();
},
render: function() {
// The ref attribute adds a reference to the component to
// this.refs when the component is mounted.
return (
<div>
<div onClick={this.clearAndFocusInput}>
Click to Focus and Reset
</div>
<input type="text" ref={(ref) => this.myTextInput = ref} />
<input
ref="theInput"
value={this.state.userInput}
onChange={this.handleChange}
type="button"
value="Focus the text input"
onClick={this.handleClick}
/>
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);
```
在这个例子中, 我们的render函数返回一个 `<input />` 实例的描述。但是真正的实例通过 `this.refs.theInput` 访问。只要带有`ref="theInput"`的子组件从 `render`被返回,`this.refs.theInput` 就可以访问正确的实例。这甚至在更高层(non-DOM)的组件上生效,比如`<Typeahead ref="myTypeahead" />`。
在这个例子中,我们获得一个对 text input **backing instance** 的引用 并且当按钮被点击时我们调用 `focus()`
对于复合组件,引用会指向一个组件类的实例所以你可以调用那个类定义的任何方法。如果你需要访问那个组件的底层的DOM节点,你可以使用 [ReactDOM.findDOMNode](/react/docs/top-level-api.html#reactdom.finddomnode) 作为一个 `安全舱口` 但是我们不推荐这样,因为它打破了封装,在大多数情况下都有一个清晰的方法来以React模式构建你的代码.
## 总结
Refs是一种很好的发送消息给特定子实例(通过流式的Reactive `props``state`来做会不方便)的方式。它们应该,不论怎样,不是你数据流通你的应用的首选。默认方式,使用Reactive数据流并为本身不是reactive的用例保存`ref`
Refs是一种很好的发送消息给特定子实例(通过流式的Reactive `props``state`来做会不方便)的方式。它们应该,不论怎样,不是你数据流通你的应用的首选。默认情况下,使用响应式数据流,并为本身不是reactive的用例保存`ref`s
### 优点:
- 你可以在你的组件类里定义任何的公开方法(比如在一个Typeahead的重置方法)然后通过refs调用那些公开方法(比如`this.refs.myTypeahead.reset()`)。
- 实行DOM测量几乎总是需要接触到"原生" 组件比如 `<input />` 并且`ReactDOM.findDOMNode(this.refs.myInput)`通过访问它的底层DOM 节点。 Refs 是唯一一个可靠的完成这件事的实际方式。
- 你可以在你的组件类里定义任何的公开方法(比如在一个Typeahead的重置方法)然后通过refs调用那些公开方法(比如`this.refs.myTypeahead.reset()`)。在大多数情况下,使用内建的React数据流更清晰,而不是使用强制的ref。
- 实行DOM测量几乎总是需要接触到 "原生" 组件比如 `<input />` 并且通过 ref 访问它的底层DOM节点。 Refs 是唯一一个可靠的完成这件事的实际方式。
- Refs 是为你自动管理的!如果子级被销毁了,它的ref也同样为你销毁了。这里不用担心内存(除非你做了一些疯狂的事情来自己保持一份引用)。
### 注意事项:
- *绝不* 在任何组件的 render 方法中访问 refs - 或者当任何组件的render方法还在调用栈上的任何地方运行时。
- 如果你想要保留Google Closure Compiler Crushing resilience,务必不要把指明为字符串的以属性来访问。这意味这你必须用`this.refs['myRefString']`访问,如果你的ref被定义为`ref="myRefString"`。
- 如果你没有用React写过数个程序,你的第一反应通常是打算试着用refs来在你的应用里"让事情发生"。如果是这样,花一些时间并且更精密的思考`state`应该属于组件层级的哪个位置。常常,这会变得清晰:正确的"拥有"那个属性的地方应该在层级的更高层上。把state放在那里往往消除了任何使用`ref`来 "让事情发生"的渴望 - 作为替代,数据流通常将完成你的目标。
- 如果你想要保留Google Closure Compiler advanced-mode crushing resilience,务必不要以属性的方式访问指明为字符串的属性。这意味这你必须用`this.refs['myRefString']`访问,如果你的ref被定义为`ref="myRefString"`。
- 如果你没有用React写过数个程序,你的第一反应通常是打算试着用refs来在你的应用里"让事情发生"。如果是这样,花一些时间并且更精密的思考`state`应该属于组件层级的哪个位置。常常,这会变得清晰:正确的"拥有"那个属性的地方应该在层级的更高层上。把state放在那里 往往消除了任何使用`ref`s 来 "让事情发生"的渴望 - 作为替代,数据流通常将完成你的目标。
- Refs 不能连接到一个 [stateless function(无状态函数)](/react/docs/reusable-components.html#stateless-functions),因为这些组件没有支持实例。你总是可以包装一个无状态组件在一个标准复合组件里并且连接一个ref到这个复合组件。

16
docs/09-tooling-integration.zh-CN.md

@ -14,7 +14,6 @@ next: addons-zh-CN.html
我们提供了CDN-hosted版本的React[在我们的下载页面](/react/downloads.html).这些预构建的文件使用UMD模块格式。将他们放进一个简单的`<script>` `React` CommonJS AMD
### 使用 master
我们[在我们的 GitHub repository](https://github.com/facebook/react)有从`master`构建的说明。我们在`build/modules` 下构建了一个CommonJS模块的树,你可以把它放到任何支持CommonJS的环境或者打包工具里。
@ -29,13 +28,21 @@ next: addons-zh-CN.html
>
> 浏览器中的JSX转换器相当大并且导致额外的本可避免的客户端计算。不要在生产环境中使用 - 见下一节。
### 投入生产: 预编译 JSX
如果你有[npm](https://www.npmjs.com/),你可以运行 `npm install -g babel`. Babel 对React v0.12 和 v0.13 有内建的支持。 标签被自动转化为它们的等价物`React.createElement(...)`, `displayName` 被自动推断并添加到所有的React.createClass 调用。
如果你有[npm](https://www.npmjs.com/),你可以运行 `npm install -g babel-cli`. Babel 对React v0.12+ 有内建支持。 标签被自动转化为它们的等价物`React.createElement(...)`, `displayName` 被自动推断并添加到所有的React.createClass 调用。
这个工具会把使用JSX语法的文件转化为简单的可直接在浏览器运行的JavaScript文件。它同样将为你监视目录并自动转化文件当他们变动时;例如:`babel --watch src/ --out-dir lib/`.
从 Babel 6 开始,默认不再包含转换。这意味这必须在运行 `babel` 命令时指定选项,或者 `.babelrc` 必须指定选项。附加的捆绑了一大批转化的包(presets)也同样需要被安装.协同React工作最常用的是 `es2015``react` presets.更多关于 Babel 变化的信息可以在 [Babel 6 博客发布的信息](http://babeljs.io/blog/2015/10/29/6.0.0/)上找到.
这里是一个要使用ES2015 语法和 React 你该怎样做的例子:
```
npm install babel-preset-es2015 babel-preset-react
babel --presets es2015,react --watch src/ --out-dir lib/
```
默认模式下带有`.js`后缀的JSX文件被转化。运行 `babel --help` 获取更多关于如何使用 Babel 的信息。
输出的例子:
@ -68,7 +75,6 @@ var HelloMessage = React.createClass({
ReactDOM.render(React.createElement(HelloMessage, { name: "John" }), mountNode);
```
### 有帮助的开源项目
开源社区已经创建了一些集成JSX到数个编辑器和构建系统的工具。见[JSX integrations](https://github.com/facebook/react/wiki/Complementary-Tools#jsx-integrations) 查看全部列表
开源社区已经创建了一些集成JSX到数个编辑器和构建系统的工具。全部列表请见[JSX integrations](https://github.com/facebook/react/wiki/Complementary-Tools#jsx-integrations) 。

7
docs/10-addons.zh-CN.md

@ -6,7 +6,7 @@ prev: tooling-integration-zh-CN.html
next: animation-zh-CN.html
---
`React.addons` 是我们放置一些用来构建React apps的有用的工具的地方。 **这些应该被认为是实验性的** 但是最终批量进入核心代码或者一个有用的工具库中:
React插件是一系列的用来构建 React app的有用模块。 **这些应该被认为是实验性的** 并趋向于比core变动更频繁。
- [`TransitionGroup` 和 `CSSTransitionGroup`](animation.html), 用来处理通常不能简单实现的动画和转换,比如在组件移除之前。
- [`LinkedStateMixin`](two-way-binding-helpers.html), 简化用户的表单输入数据与组件状态的协调。
@ -14,12 +14,11 @@ next: animation-zh-CN.html
- [`createFragment`](create-fragment.html), 创建一组外键的子级。
- [`update`](update.html), 一个使不可变数据在JavaScript里更易处理的辅助函数。
- [`PureRenderMixin`](pure-render-mixin.html), 一个特定情况下的性能优化器。
- [`shallowCompare`](shallow-compare.html), 一个辅助函数,用来对 props 和 state在组件里 执行浅比较 以决定一个组件是否应该更新。
下面的插件只存在开发版(未压缩)React中:
- [`TestUtils`](test-utils.html), 用于写测试用例的简单的辅助工具(仅存在于未压缩版本)。
- [`Perf`](perf.html), 用于测量性能并给你提示哪里可以优化。
要获取插件,使用 `react-with-addons.js` (和它的压缩副本)而不是通常的 `react.js`
当从npm使用react包时,简单的用`require('react/addons')` 代替 `require('react')` 来获取带有所有插件的React。
要获取插件,单独从npm安装他们(例如 `npm install react-addons-pure-render-mixin`).我们不支持使用插件如果你没有用npm.

15
docs/10.1-animation.zh-CN.md

@ -17,7 +17,7 @@ React 提供了一个 `ReactTransitionGroup` 插件作为动画的底层API,和
`ReactCSSTransitionGroup``ReactTransitions` 的接口。这是一个简单的元素,包裹了所有你感兴趣的动画组件。这里是一个淡入和淡出列表项目的例子。
```javascript{28-30}
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
var TodoList = React.createClass({
getInitialState: function() {
@ -29,7 +29,7 @@ var TodoList = React.createClass({
this.setState({items: newItems});
},
handleRemove: function(i) {
var newItems = this.state.items;
var newItems = this.state.items.slice();
newItems.splice(i, 1);
this.setState({items: newItems});
},
@ -101,11 +101,11 @@ var TodoList = React.createClass({
```css
.example-appear {
opacity: 0.01;
transition: opacity .5s ease-in;
}
.example-appear.example-appear-active {
opacity: 1;
transition: opacity .5s ease-in;
}
```
@ -173,7 +173,7 @@ var TodoList = React.createClass({
在上面的例子中,我们渲染了一系列的项目到`ReactCSSTransitionGroup`里。然而 `ReactCSSTransitionGroup` 的子级同样可以是一个或零个项目。这使它能够动画化单个元素的进入和离开。同样,你可以动画化一个新的元素替换当前元素。例如,我们可以像这样实现一个简单的图片轮播器:
```javascript{10-12}
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
var ImageCarousel = React.createClass({
propTypes: {
@ -201,7 +201,7 @@ var ImageCarousel = React.createClass({
## 底层 API: `ReactTransitionGroup`
`ReactTransitionGroup`是动画的基础。它通过 `React.addons.TransitionGroup` 访问。当子级被声明式的从其中添加或移除(就像上面的例子)时,特殊的生命周期挂钩会在它们上面被调用。
`ReactTransitionGroup`是动画的基础。它通过 `require('react-addons-transition-group')` 访问。当子级被声明式的从其中添加或移除(就像上面的例子)时,特殊的生命周期挂钩会在它们上面被调用。
### `componentWillAppear(callback)`
@ -237,11 +237,8 @@ var ImageCarousel = React.createClass({
</ReactTransitionGroup>
```
每一个React能渲染的DOM组件都是可用的。然而,`组件`不需要是一个DOM组件。它可以是任何你想要的React组件;甚至是你自己已经写好的!
每一个React能渲染的DOM组件都是可用的。然而,`组件`不需要是一个DOM组件。它可以是任何你想要的React组件;甚至是你自己已经写好的!只要写 `component={List}` 你的组件会收到 `this.props.children`
> 注意:
>
> v0.12之前,当使用DOM组件时,`组件` prop 需要是一个对`React.DOM.*`的引用。既然组件简单的被传递到 `React.createElement`,它现在必然是一个字符串。复合组件必须传递工厂函数(factory)。
任何额外的、用户定义的属性将会成为已渲染的组件的属性。例如,以下是你将如何渲染一个带有css类的 `<ul>`

Loading…
Cancel
Save