天天看点

【译】参考手册-React组件

react version: 15.4.2

组件能够让你将UI拆分为多个独立自治并可重用的部分。在 <code>React</code> 中提供了 <code>React.Component</code>。

<code>React.Component</code> 是一个抽象基类,直接引用 <code>React.Component</code> 无太大意义。反而,我们会用子类来继承它,并至少定义一个 <code>render()</code> 方法。

通常您将使用纯 JavaScript class 来定义一个 <code>React</code> 组件:

如果您还没有使用ES6,可以使用 <code>React.createClass</code> 来替代。从 Using React without ES6 了解更多。

每个组件都有几个 <code>生命周期方法</code>,您可以不同的阶段插入自己的逻辑代码。以 <code>will</code> 开头的方法将在事情发生前被调用,以 <code>did</code> 开头的方法将在事情发生后被调用。

以下的方法,将在组件实例被创建和插入到DOM前被调用:

<code>constructor()</code>

<code>componentWillMount()</code>

<code>render()</code>

<code>componentDidMount()</code>

属性或状态变化将会引发更新。以下方法将在重绘之前被调用:

<code>componentWillReceiveProps()</code>

<code>shouldComponentUpdate()</code>

<code>componentWillUpdate()</code>

<code>componentDidUpdate()</code>

以下方法将在组件开始从DOM移除时被调用:

<code>componentWillUnmount()</code>

每个组件也都会提供以下几个API:

<code>setState()</code>

<code>forceUpdate()</code>

<code>defaultProps</code>

<code>displayName</code>

<code>props</code>

<code>state</code>

<code>render()</code> 方法是必须的。

当调用 <code>render()</code> 方法时,将检查 <code>this.props</code> 和 <code>this.state</code> 并返回单个React元素。这个元素可以是原生DOM组件,如 <code>&lt;div /&gt;</code>,也可以是你自定义的复合组件。

如果你不想渲染任何内容,你可以返回 <code>null</code> 或者是 <code>false</code>。当返回 <code>null</code> 或 <code>false</code> 时, <code>ReactDOM.findDOMNode(this)</code> 也将返回 <code>null</code>。

<code>render()</code> 函数应该是纯函数,这意味着你不应该修改组件状态,每次调用都应该返回同样的结果,同时也不要直接和浏览器交互(不要操作DOM)。如果你想要操作DOM,请使用 <code>componentDidMount()</code> 或其他生命周期方法来替代。使用纯粹的 <code>render()</code> 可以使组件易于理解。

注意 <code>render()</code> 不会在 <code>shouldComponentUpdate()</code> 返回 <code>false</code> 的时候被调用。

React组件的构造函数会在挂载前被调用。当我们在 <code>React.Component</code> 的子类中实现构建函数时,我们应该在所有语句之前优先调用 <code>super(props)</code>。反之,在构造函数中访问 <code>this.props</code> 将会是未定义,这可能会导致bugs。

构造函数是初始化状态的地方。如果你不需要初始化状态,且不绑定方法,那么你不必要实现构造函数。

如果你确信,你可以使用 <code>props</code> 来初始化状态。以下是一个合法的 <code>React.Component</code> 子类构造函数:

当心这种模式,它能够有效的 "forks" 属性且可能会导致bugs。你通常可以使用状态提升来替代同步属性到状态。

如果你想使用 <code>state</code> 来 "fork" <code>props</code>,你还需要实现 <code>componentWillReceiveProps(nextProps)</code> 来保持状态是最新的。但是状态提升通常是更容易且不容易出错的。

<code>componentWillMount()</code> 将在挂载发生前,被立即调用。它会在 <code>render</code> 之前调用,因此在该方法中设置状态将不会触发重新渲染。避免在此方法中引入任何有副作用的行为或者订阅。

这是在服务端渲染中唯一被调用的生命周期钩子。通常,我们用来替代 <code>constructor()</code>。

<code>componentDidMount()</code> 将在组件挂载之后立即被调用。需要使用 DOM 节点的初始化应该放在这里。如果你需要加载远端数据,这也是处理网络请求的好地方。在这个方法中设置状态将会触发重绘。

<code>componentWillReceiveProps()</code> 将在已经挂载的组件接受到新属性前被调用。如果你需要更新状态来响应属性变化(例如,重置状态),你可以比较 <code>this.props</code> 和 <code>nextProps</code>,然后使用 <code>this.setState()</code> 来处理状态变化。

请注意,就算属性没有变化,React也可能会调用此方法,因此如果你只想到处理有变更的情况,那么请确保比较当前值和下一次的值。这种情况在父组件变更导致你的组件重绘时可能会发生。

在挂载阶段初始化属性React不会调用 <code>componentWillReceiveProps</code>。如果一些组件的属性可能会更新,它仅会调用该方法。调用 <code>this.setState</code> 通常不会触发 <code>componentWillReceiveProps</code>。

使用 <code>shouldComponentUpdate</code> 让React知道组件的输出不会受到当前状态和属性变更的影响。默认行为是当每次状态变更时都会引发重绘,绝大多数情况下,您应该依赖默认行为。

当收到新的状态或者属性时,将会调用 <code>shouldComponentUpdate()</code>。默认值是 <code>true</code>。在初次渲染或调用 <code>forceUpdate()</code> 时,<code>shouldComponentUpdate()</code> 将不会被调用。

返回 <code>false</code> 也不会阻止子组件在它们自己的状态变化时重绘。

目前,当 <code>shouldComponentUpdate()</code> 返回 <code>false</code>,<code>componentWillUpdate()</code>, <code>render()</code>, 和 <code>componentDidUpdate()</code> 都不会被调用。请注意,未来React可能将 <code>shouldComponentUpdate()</code> 作为一个提示而不是一个强制指令,就算是返回 <code>false</code> 仍然有可能导致组件重绘。

如果你在监控分析之后,发现特定组件确实非常缓慢,那么可以将其修改为实现了使用浅表属性和状态比较的 <code>shouldComponentUpdate()</code> 方法的 <code>React.PureComponent</code>。如果你有信心手动确认,你可以比较 <code>this.props</code> 与 <code>nextProps</code> 以及 <code>this.state</code> 与 <code>nextState</code> 的值来告诉React本次更新是可以跳过的。

当接收到新的属性或者状态时,<code>componentWillUpdate()</code> 将会在重绘前被立即调用。可以在此处放置一些重绘前的处理逻辑。这个方法在初次绘制时不会被调用。

注意你也不能在此处调用 <code>this.setState()</code>。如果你需要更新状态来响应属性变化,请使用 <code>componentWillReceiveProps()</code> 替代。

当 <code>shouldComponentUpdate()</code> 返回 false 时,<code>componentWillUpdate()</code> 将不会被调用。

在更新完成之后,<code>componentDidUpdate()</code> 会被立即调用。初次绘制不会调用该方法。

在这里可以操作组件更新之后的DOM。在你比较了当前属性和上一次属性之后,这里也适合处理网络请求。(例如:如果属性没有变化,可能不需要一个网络请求。)

在组件卸载和释放之前,将会立即调用 <code>componentWillUnmount()</code>。可以在该方法中,执行一些清理动作,如无效的定时器,取消网络请求,或者是清理在 <code>componentDidMount()</code> 中创建的DOM元素。

执行它会执行一次浅表复制,将 <code>nextState</code> 合并到当前状态上。这也是从事件处理函数和服务请求回调中触发UI更新的主要方法。

第一个参数可以是一个对象(包含0个或多个要更新的key)或者是一个返回包含更新key的对象的函数(传入状态和属性)。

简单对象用法如下:

它也可能传递如下签名 <code>function(state, props) =&gt; newState</code> 的函数。这将引入一个原子更新,会在设置值之前先查看上一次的状态和属性。例如,我们想每次增加 <code>props.step</code> 指定的值:

第二个参数是一个可选的回调函数,它将在 <code>setState</code> 完成和组件重绘之后执行一次。通常,我们建议在 <code>componentDidUpdate()</code> 中处理这样的逻辑。

<code>setState()</code> 不会立即更新 <code>this.state</code>,仅会创建一个挂起的状态转换。调用此方法之后访问 <code>this.state</code> 可能会返回现有值。

不能确保 <code>setState</code> 是同步操作,多次调用 <code>setState</code> 可能会进行批处理以提高性能。

<code>setState()</code> 将总是导致重绘,除非 <code>shouldComponentUpdate()</code> 返回 <code>false</code>。如果使用可变对象且不能在 <code>shouldComponentUpdate()</code> 中实现条件重绘逻辑,那么可以仅在当前状态与之前不同时,再调用 <code>setState()</code> 来避免不必要的重绘。

默认情况下,当你的组件状态和属性变化时,组件将会被重绘。如果你的 <code>render()</code> 方法中依赖一些其他的数据,你可以调用 <code>forceUpdate()</code> 来告诉React需要重绘。

调用 <code>forceUpdate()</code> 将导致组件跳过 <code>shouldComponentUpdate()</code> 直接调用 <code>render()</code>。这也将触发子组件正常的生命周期方法,包括每个子组件的 <code>shouldComponentUpdate()</code>。React仍然将只更新标记变化的DOM元素。

通常,你应该避免使用 <code>forceUpdate()</code>,仅在 <code>render()</code> 中只读取 <code>this.props</code> 和 <code>this.state</code>。

能够在组件类自身上定义 <code>defaultProps</code> 属性,它将为属性设置默认值。当属性未定义时才会被设置为默认属性值,如果属性值被设置为null,则不会被设置为默认属性值。示例如下:

当 <code>props.color</code> 没有提供时,它将被设置为默认值 <code>'blue'</code>:

如果 <code>props.color</code> 被设置为 null,它仍然是 null:

<code>displayName</code> 字符串用于调试信息。JSX 会自动设置这个值;查看 深入JSX 了解更多。

可以在组件类自身上定义 <code>propTypes</code> 属性,用来确定属性的类型。它是属性名称和定义在 <code>React.PropTypes</code> 中类型的一个映射。在开发模式中,如果碰到不合法的属性,那么控制台将会打印警告。产线模式下,属性类型检查基于性能考虑将会被跳过。

例如,以下代码确保 <code>color</code> 属性是字符串:

我们建议您尽可能的使用 Flow,以便使用编译时的类型检查,而不是运行时的类型检查。查看 Flow 对 React 的内置支持 来轻松的在 React 应用中使用静态分析。

<code>this.props</code> 包含了组件调用者定义的属性。查看 组件和属性 了解更多。

<code>this.props.children</code> 是一个特别的属性,通常是由 JSX 表达式的子标签定义,而不是组件本身的标签。

<code>state</code> 包含了组件特定的可能随时间变化而变化的数据。 <code>state</code> 是用户自定义的,它也是一个纯粹的JavaScript对象。

不需要在 <code>render()</code> 中使用的数据,不必要放在 <code>state</code> 上。例如,您可以直接在实例上存储定时器ID。

查看 快速起步-状态和生命周期 了解更多。

调用 <code>setState()</code> 来替代直接修改 <code>this.state</code>。保持 <code>this.state</code> 是不可变的。