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.

222 lines
7.4 KiB

---
id: component-specs-zh-CN
title: 组件的规范和生命周期
Upgrade to Jekyll 3 Full list of changes is at https://jekyllrb.com/docs/upgrading/2-to-3/. The tl;dr of it is: - Relative permalinks were removed, so all the files in the `docs` subdirectory need their permalink to be prefixed with `docs/` - `post` and `page` types were renamed to `posts` and `pages` respectively - `jekyll-paginate`, `pygments` and `redcarpet` are all now optional, so I needed to explicitly add it to the Gemfile. Jekyll now uses `rouge` rather than `pygments` for syntax highlighting, but rouge does not support highlighting individual lines (`hl_lines`) so we need to continue using Pygments. - Layout metadata (eg. `sectionid`) is now on a `layout` variable rather than `page` Tested the following pages and confirmed that they all work: - "Docs" link (getting started page): http://127.0.0.1:4000/react/docs/getting-started.html - Downloads: http://127.0.0.1:4000/react/downloads.html - Tutorial: http://127.0.0.1:4000/react/docs/tutorial.html - A few pages under the "docs" subdirectory, to confirm they're working properly: - http://127.0.0.1:4000/react/docs/addons.html - http://127.0.0.1:4000/react/docs/why-react.html - http://127.0.0.1:4000/react/docs/create-fragment.html - A few tips: - http://127.0.0.1:4000/react/tips/false-in-jsx.html - http://127.0.0.1:4000/react/tips/style-props-value-px.html - Non-English versions of the page: - http://127.0.0.1:4000/react/docs/getting-started-it-IT.html - http://127.0.0.1:4000/react/docs/getting-started-ja-JP.html
9 years ago
permalink: docs/component-specs-zh-CN.html
prev: component-api-zh-CN.html
next: tags-and-attributes-zh-CN.html
---
## 组件规范(Specifications)
当调用 `React.createClass()` 创建一个组件类时,你应该提供一个包含有 `render` 方法以及可选的其他生命周期方法的 规范(Specifications)对象.
> 注意:
>
> 同样可以使用单纯的 JavaScript 类作为组件类. 这些类可以实现大多数相同的方法,虽然有一些不同.更多关于不同的信息,请阅读我们关于[ES6 classes](/react/docs/reusable-components.html#es6-classes)的文档.
### render
```javascript
ReactElement render()
```
`render()` 是必须的
当被调用时,它应该检查 `this.props``this.state` 并返回单个子元素.这个子元素即可以是一个 对原生DOM的虚拟表达(比如 `<div />``React.DOM.div()`)也可以是其他你自定义的复合组件.
你也可以返回 `null``false` 来指示你不想要任何东西被渲染.幕后,React 渲染一个 `<noscript>` tag 来与我们当前的diffing算法协同工作.当返回 `null``false` ,`ReactDOM.findDOMNode(this)` 会返回 `null`.
`render()` 函数应该是纯净的,意味着它不改变组件的状态,它在每次调用时返回相同的结果,并且它不读和写 DOM 或者其他方式与浏览器互动(例如,使用 `setTimeout`).如果你需要与浏览器互动,在 `componentDidMount()` 里执行你的工作,或者其他生命周期方法里.保持 `render()` 纯净使服务器渲染更实用并且让组件更容易被思考.
### getInitialState
```javascript
object getInitialState()
```
当组件被挂载时调用一次.返回值会被用作为 `this.state` 的初始值.
> 注意:
>
> 这个方法在从 `React.Component` 扩展的 ES6 `class` 组件里不可用。 更多的信息,请阅读我们关于[ES6 classes](/react/docs/reusable-components.html#es6-classes)的文档.
### getDefaultProps
```javascript
object getDefaultProps()
```
在类被创建时调用一次并被缓存.在这个mapping里的值会被设置给 `this.props` 如果父组件没有指定对应的 prop (例如 使用一个 `in` 检查).
这个方法在任何实例被创建之前调用,因此不能依赖于 `this.props`.另外,小心,任何被 `getDefaultProps()`返回的复杂对象会被跨实例共享,而不是被拷贝.
### propTypes
```javascript
object propTypes
```
`propTypes` 对象允许你验证传递到你的组建的 props.更多关于 `propTypes` 的信息,见 [Reusable Components](/react/docs/reusable-components.html).
### mixins
```javascript
array mixins
```
`mixins` 数组允许你用 mixins 来在多个组件间共享行为.更多关于 mixins 的信息,见 [Reusable Components](/react/docs/reusable-components.html).
### statics
```javascript
object statics
```
`statics` 对象允许你定义可以在组件类上调用的静态方法.例如:
```javascript
var MyComponent = React.createClass({
statics: {
customMethod: function(foo) {
return foo === 'bar';
}
},
render: function() {
}
});
MyComponent.customMethod('bar'); // true
```
在这个块里定义的方法是 _static_,意味着你可以在任何组件实例被创建前运行他们,并且这些方法没有对你组件的 props 或 state 的访问权.如果你在静态方法里检查props的值,把调用者作为参数传入props给静态函数.
### displayName
```javascript
string displayName
```
`displayName` 字符串被用在调试信息.JSX 自动设置这个值;见 [JSX in Depth](/react/docs/jsx-in-depth.html#the-transform).
## Lifecycle Methods
多种方法在组件生命周期的特定点上被执行.
### Mounting: componentWillMount
```javascript
void componentWillMount()
```
被调用一次,即在客户端也在服务端,在最初的渲染发生之前 立即被调用.如果你在这个方法里调用 `setState` , `render()` 将会看到更新的 state 并不论state的变化只执行一次.
### Mounting: componentDidMount
```javascript
void componentDidMount()
```
被调用一次,只在客户端(不在服务端),在最初的渲染发生之后 立即被调用.在生命周期的这个点上,你可以访问任何对你的子级的refs (比如 访问底层的DOM表达).子组件的 `componentDidMount()` 方法在父组件之前被调用.
如果你想与其他 JavaScript 框架整合,用 `setTimeout``setInterval` 设置timers,或者发送 AJAX 请求,执行这些操作在此方法中.
### Updating: componentWillReceiveProps
```javascript
void componentWillReceiveProps(
object nextProps
)
```
当一个组件收到新的props时被调用.这个方法不会为最初的渲染调用.
使用它作为响应 prop 转换的时机(在`render()` 被用 `this.setState()` 更新state调用 之前) .旧的 props 可以通过 `this.props` 访问. 在这个函数里调用 `this.setState()` 不会触发任何额外的渲染.
```javascript
componentWillReceiveProps: function(nextProps) {
this.setState({
likesIncreasing: nextProps.likeCount > this.props.likeCount
});
}
```
> 注意:
>
> 并没有类似的 `componentWillReceiveState` 方法. 一个即将到来的 prop 转变可能会导致一个 state 变化,但是反之不是. 如果你需要实现一个对 state 变化相应的操作,使用 `componentWillUpdate`.
### Updating: shouldComponentUpdate
```javascript
boolean shouldComponentUpdate(
object nextProps, object nextState
)
```
当新的props或者state被收到,在渲染前被调用.这个方法不会在最初的渲染或者 `forceUpdate` 时被调用.
使用此方法作为一个 `return false` 的时机,当你确定新的 props 和 state 的转换不需要组件更新时.
```javascript
shouldComponentUpdate: function(nextProps, nextState) {
return nextProps.id !== this.props.id;
}
```
如果 `shouldComponentUpdate` 返回false, `render()` 会在下次state变化前被完全跳过. 另外,`componentWillUpdate` 和 `componentDidUpdate` 将不会被调用.
默认情况下, `shouldComponentUpdate` 总是返回 `true` 来阻止当 `state` 突变时的细微bug,但是如果你仔细的把 `state` 作为不变量对待并只从 `render()`里的 `props``state`读,你就可以用一个比较旧的props和state与他们的替换者的实现来重写 `shouldComponentUpdate`.
如果性能是瓶颈,尤其是随着成百上千的组件,使用 `shouldComponentUpdate` 来加速你的app.
### Updating: componentWillUpdate
```javascript
void componentWillUpdate(
object nextProps, object nextState
)
```
当新的props或者state被接受时,在渲染前被立即调用.这个方法不会被初始渲染调用.
使用这个方法作为 在更新发生前执行一些准备 的时机.
> Note:
>
> 你 *不能* 在这个方法里使用 `this.setState()` .如果你需要响应一个prop变化来更新state,使用 `componentWillReceiveProps` 来替代.
### Updating: componentDidUpdate
```javascript
void componentDidUpdate(
object prevProps, object prevState
)
```
在组件的更新被刷新到DOM后立即被调用.这个方法不会被初始渲染调用.
使用这个方法作为 当组件被更新后在DOM上操作 的时机.
### Unmounting: componentWillUnmount
```javascript
void componentWillUnmount()
```
在组件被从DOM卸载 前 被立即调用.
在这个方法里执行一些必要的清理操作,比如无效化 timers 或者清理任何被 `componentDidMount` 创建的DOM元素.