diff --git a/content/docs/reference-react-component.md b/content/docs/reference-react-component.md index ecb4d087c0..975cf134ef 100644 --- a/content/docs/reference-react-component.md +++ b/content/docs/reference-react-component.md @@ -15,11 +15,11 @@ redirect_from: - "tips/use-react-with-other-libraries.html" --- -This page contains a detailed API reference for the React component class definition. It assumes you're familiar with fundamental React concepts, such as [Components and Props](/docs/components-and-props.html), as well as [State and Lifecycle](/docs/state-and-lifecycle.html). If you're not, read them first. +本章节提供了 React class 组件的详细 API 参考。本章节默认你已熟悉基本的 React 概念,例如 [组件 & Props](/docs/components-and-props.html),以及 [State & 生命周期](/docs/state-and-lifecycle.html)等。如果你还未熟悉,请先阅读之前章节进行学习。 -## Overview {#overview} +## 概览 {#overview} -React lets you define components as classes or functions. Components defined as classes currently provide more features which are described in detail on this page. To define a React component class, you need to extend `React.Component`: +React 的组件可以定义为 class 或函数的形式。class 组件目前提供了更多的功能,这些功能将在此章节中详细介绍。如需定义 class 组件,需要继承 `React.Component`: ```js class Welcome extends React.Component { @@ -29,36 +29,36 @@ class Welcome extends React.Component { } ``` -The only method you *must* define in a `React.Component` subclass is called [`render()`](#render). All the other methods described on this page are optional. +在 `React.Component` 的子类中有个必须定义的 [`render()`](#render) 函数。本章节介绍其他方法均为可选。 -**We strongly recommend against creating your own base component classes.** In React components, [code reuse is primarily achieved through composition rather than inheritance](/docs/composition-vs-inheritance.html). +**我们强烈建议你不要创建自己的组件基类。** 在 React 组件中,[代码重用的主要方式是组合而不是继承](/docs/composition-vs-inheritance.html)。 ->Note: +>注意: > ->React doesn't force you to use the ES6 class syntax. If you prefer to avoid it, you may use the `create-react-class` module or a similar custom abstraction instead. Take a look at [Using React without ES6](/docs/react-without-es6.html) to learn more. +>React 并不会强制你使用 ES6 的 class 语法。如果你倾向于不使用它,你可以使用 `create-react-class` 模块或类似的自定义抽象来代替。请查阅[不使用 ES6](/docs/react-without-es6.html) 了解更多。 -### The Component Lifecycle {#the-component-lifecycle} +### 组件的生命周期 {#the-component-lifecycle} -Each component has several "lifecycle methods" that you can override to run code at particular times in the process. **You can use [this lifecycle diagram](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/) as a cheat sheet.** In the list below, commonly used lifecycle methods are marked as **bold**. The rest of them exist for relatively rare use cases. +每个组件都包含“生命周期方法”,你可以重写这些方法,以便于在运行过程中特定的阶段执行这些方法。**你可以使用此[生命周期图谱](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)作为速查表**。在下述列表中,常用的生命周期方法会被加粗。其余生命周期函数的使用则相对罕见。 -#### Mounting {#mounting} +#### 挂载 {#mounting} -These methods are called in the following order when an instance of a component is being created and inserted into the DOM: +当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下: - [**`constructor()`**](#constructor) - [`static getDerivedStateFromProps()`](#static-getderivedstatefromprops) - [**`render()`**](#render) - [**`componentDidMount()`**](#componentdidmount) ->Note: +>注意: > ->These methods are considered legacy and you should [avoid them](/blog/2018/03/27/update-on-async-rendering.html) in new code: +>下述生命周期方法即将过时,在新代码中应该[避免使用它们](/blog/2018/03/27/update-on-async-rendering.html): > >- [`UNSAFE_componentWillMount()`](#unsafe_componentwillmount) -#### Updating {#updating} +#### 更新 {#updating} -An update can be caused by changes to props or state. These methods are called in the following order when a component is being re-rendered: +当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下: - [`static getDerivedStateFromProps()`](#static-getderivedstatefromprops) - [`shouldComponentUpdate()`](#shouldcomponentupdate) @@ -66,50 +66,50 @@ An update can be caused by changes to props or state. These methods are called i - [`getSnapshotBeforeUpdate()`](#getsnapshotbeforeupdate) - [**`componentDidUpdate()`**](#componentdidupdate) ->Note: +>注意: > ->These methods are considered legacy and you should [avoid them](/blog/2018/03/27/update-on-async-rendering.html) in new code: +>下述方法即将过时,在新代码中应该[避免使用它们](/blog/2018/03/27/update-on-async-rendering.html): > >- [`UNSAFE_componentWillUpdate()`](#unsafe_componentwillupdate) >- [`UNSAFE_componentWillReceiveProps()`](#unsafe_componentwillreceiveprops) -#### Unmounting {#unmounting} +#### 卸载 {#unmounting} -This method is called when a component is being removed from the DOM: +当组件从 DOM 中移除时会调用如下方法: - [**`componentWillUnmount()`**](#componentwillunmount) -#### Error Handling {#error-handling} +#### 错误处理 {#error-handling} -These methods are called when there is an error during rendering, in a lifecycle method, or in the constructor of any child component. +当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用如下方法: - [`static getDerivedStateFromError()`](#static-getderivedstatefromerror) - [`componentDidCatch()`](#componentdidcatch) -### Other APIs {#other-apis} +### 其他 APIs {#other-apis} -Each component also provides some other APIs: +组件还提供了一些额外的 API: - [`setState()`](#setstate) - [`forceUpdate()`](#forceupdate) -### Class Properties {#class-properties} +### class 属性 {#class-properties} - [`defaultProps`](#defaultprops) - [`displayName`](#displayname) -### Instance Properties {#instance-properties} +### 实例属性 {#instance-properties} - [`props`](#props) - [`state`](#state) * * * -## Reference {#reference} +## 参考 {#reference} -### Commonly Used Lifecycle Methods {#commonly-used-lifecycle-methods} +### 常用的生命周期方法 {#commonly-used-lifecycle-methods} -The methods in this section cover the vast majority of use cases you'll encounter creating React components. **For a visual reference, check out [this lifecycle diagram](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/).** +本节中的方法涵盖了创建 React 组件时能遇到的绝大多数用例。**想要更好了解这些方法,可以参考[生命周期图谱](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)。** ### `render()` {#render} @@ -117,23 +117,23 @@ The methods in this section cover the vast majority of use cases you'll encounte render() ``` -The `render()` method is the only required method in a class component. +`render()` 方法是 class 组件中唯一必须实现的方法。 -When called, it should examine `this.props` and `this.state` and return one of the following types: +当 `render` 被调用时,它会检查 `this.props` 和 `this.state` 的变化并返回以下类型之一: -- **React elements.** Typically created via [JSX](/docs/introducing-jsx.html). For example, `
` and `` are React elements that instruct React to render a DOM node, or another user-defined component, respectively. -- **Arrays and fragments.** Let you return multiple elements from render. See the documentation on [fragments](/docs/fragments.html) for more details. -- **Portals**. Let you render children into a different DOM subtree. See the documentation on [portals](/docs/portals.html) for more details. -- **String and numbers.** These are rendered as text nodes in the DOM. -- **Booleans or `null`**. Render nothing. (Mostly exists to support `return test && ` pattern, where `test` is boolean.) +- **React 元素**。通常通过 JSX 创建。例如,`
` 会被 React 渲染为 DOM 节点,`` 会被 React 渲染为自定义组件,无论是 `
` 还是 `` 均为 React 元素。 +- **数组或 fragments**。 使得 render 方法可以返回多个元素。欲了解更多详细信息,请参阅 [fragments](/docs/fragments.html) 文档。 +- **Portals**。可以渲染子节点到不同的 DOM 子树中。欲了解更多详细信息,请参阅有关 [portals](/docs/portals.html) 的文档 +- **字符串或数值类型**。它们在 DOM 中会被渲染为文本节点 +- **布尔类型或 `null`**。什么都不渲染。(主要用于支持返回 `test && ` 的模式,其中 test 为布尔类型。) -The `render()` function should be pure, meaning that it does not modify component state, it returns the same result each time it's invoked, and it does not directly interact with the browser. +`render()` 函数应该为纯函数,这意味着在不修改组件 state 的情况下,每次调用时都返回相同的结果,并且它不会直接与浏览器交互。 -If you need to interact with the browser, perform your work in `componentDidMount()` or the other lifecycle methods instead. Keeping `render()` pure makes components easier to think about. +如需与浏览器进行交互,请在 `componentDidMount()` 或其他生命周期方法中执行你的操作。保持 `render()` 为纯函数,可以使组件更容易思考。 -> Note +> 注意 > -> `render()` will not be invoked if [`shouldComponentUpdate()`](#shouldcomponentupdate) returns false. +> 如果 `shouldComponentUpdate()` 返回 false,则不会调用 `render()`。 * * * @@ -143,47 +143,47 @@ If you need to interact with the browser, perform your work in `componentDidMoun constructor(props) ``` -**If you don't initialize state and you don't bind methods, you don't need to implement a constructor for your React component.** +**如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。** -The constructor for a React component is called before it is mounted. When implementing the constructor for a `React.Component` subclass, you should call `super(props)` before any other statement. Otherwise, `this.props` will be undefined in the constructor, which can lead to bugs. +在 React 组件挂载之前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应在其他语句之前前调用 `super(props)`。否则,`this.props` 在构造函数中可能会出现未定义的 bug。 -Typically, in React constructors are only used for two purposes: +通常,在 React 中,构造函数仅用于以下两种情况: -* Initializing [local state](/docs/state-and-lifecycle.html) by assigning an object to `this.state`. -* Binding [event handler](/docs/handling-events.html) methods to an instance. +* 通过给 `this.state` 赋值对象来初始化[内部 state](/docs/state-and-lifecycle.html)。 +* 为[事件处理函数](/docs/handling-events.html)绑定实例 -You **should not call `setState()`** in the `constructor()`. Instead, if your component needs to use local state, **assign the initial state to `this.state`** directly in the constructor: +在 `constructor()` 函数中**不要调用 `setState()` 方法**。如果你的组件需要使用内部 state,请直接在构造函数中为 **`this.state` 赋值初始 state**: ```js constructor(props) { super(props); - // Don't call this.setState() here! + // 不要在这里调用 this.setState() this.state = { counter: 0 }; this.handleClick = this.handleClick.bind(this); } ``` -Constructor is the only place where you should assign `this.state` directly. In all other methods, you need to use `this.setState()` instead. +只能在构造函数中直接为 `this.state` 赋值。如需在其他方法中赋值,你应使用 `this.setState()` 替代。 -Avoid introducing any side-effects or subscriptions in the constructor. For those use cases, use `componentDidMount()` instead. +要避免在构造函数中引入任何副作用或订阅。如遇到此场景,请将对应的操作放置在 `componentDidMount` 中。 ->Note +>注意 > ->**Avoid copying props into state! This is a common mistake:** +>**避免将 props 的值复制给 state!这是一个常见的错误:** > >```js >constructor(props) { > super(props); -> // Don't do this! +> // 不要这样做 > this.state = { color: props.color }; >} >``` > ->The problem is that it's both unnecessary (you can use `this.props.color` directly instead), and creates bugs (updates to the `color` prop won't be reflected in the state). +>如此做毫无必要(你可以直接使用 `this.props.color`),同时还产生了 bug(更新 prop 中的 `color` 时,并不会影响 state)。 > ->**Only use this pattern if you intentionally want to ignore prop updates.** In that case, it makes sense to rename the prop to be called `initialColor` or `defaultColor`. You can then force a component to "reset" its internal state by [changing its `key`](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) when necessary. +>**只有在你刻意忽略 prop 更新的情况下使用。**此时,应将 prop 重命名为 `initialColor` 或 `defaultColor`。必要时,你可以[修改它的 `key`](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key),以强制“重置”其内部 state。 > ->Read our [blog post on avoiding derived state](/blog/2018/06/07/you-probably-dont-need-derived-state.html) to learn about what to do if you think you need some state to depend on the props. +>请参阅关于[避免派生状态的博文](/blog/2018/06/07/you-probably-dont-need-derived-state.html),以了解出现 state 依赖 props 的情况该如何处理。 * * * @@ -194,11 +194,11 @@ Avoid introducing any side-effects or subscriptions in the constructor. For thos componentDidMount() ``` -`componentDidMount()` is invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request. +`componentDidMount()` 会在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方。 -This method is a good place to set up any subscriptions. If you do that, don't forget to unsubscribe in `componentWillUnmount()`. +这个方法是比较适合添加订阅的地方。如果添加了订阅,请不要忘记在 `componentWillUnmount()` 里取消订阅 -You **may call `setState()` immediately** in `componentDidMount()`. It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the `render()` will be called twice in this case, the user won't see the intermediate state. Use this pattern with caution because it often causes performance issues. In most cases, you should be able to assign the initial state in the `constructor()` instead. It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position. +你可以在 `componentDidMount()` 里**可以直接调用 `setState()`**。它将触发额外渲染,但此渲染会发生在浏览器更新屏幕之前。如此保证了即使在 `render()` 两次调用的情况下,用户也不会看到中间状态。请谨慎使用该模式,因为它会导致性能问题。通常,你应该在 `constructor()` 中初始化 state。如果你的渲染依赖于 DOM 节点的大小或位置,比如实现 modals 和 tooltips 等情况下,你可以使用此方式处理 * * * @@ -208,26 +208,26 @@ You **may call `setState()` immediately** in `componentDidMount()`. It will trig componentDidUpdate(prevProps, prevState, snapshot) ``` -`componentDidUpdate()` is invoked immediately after updating occurs. This method is not called for the initial render. +`componentDidUpdate()` 会在更新后会被立即调用。首次渲染不会执行此方法。 -Use this as an opportunity to operate on the DOM when the component has been updated. This is also a good place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed). +当组件更新后,可以在此处对 DOM 进行操作。如果你对更新前后的 props 进行了比较,也可以选择在此处进行网络请求。(例如,当 props 未发生变化时,则不会执行网络请求)。 ```js componentDidUpdate(prevProps) { - // Typical usage (don't forget to compare props): + // 典型用法(不要忘记比较 props): if (this.props.userID !== prevProps.userID) { this.fetchData(this.props.userID); } } ``` -You **may call `setState()` immediately** in `componentDidUpdate()` but note that **it must be wrapped in a condition** like in the example above, or you'll cause an infinite loop. It would also cause an extra re-rendering which, while not visible to the user, can affect the component performance. If you're trying to "mirror" some state to a prop coming from above, consider using the prop directly instead. Read more about [why copying props into state causes bugs](/blog/2018/06/07/you-probably-dont-need-derived-state.html). +你也可以在 `componentDidUpdate()` 中**直接调用 `setState()`**,但请注意**它必须被包裹在一个条件语件里**,正如上述的例子那样进行处理,否则会导致死循环。它还会导致额外的重新渲染,虽然用户不可见,但会影响组件性能。不要将 props “镜像”给 state,请考虑直接使用 props。 欲了解更多有关内容,请参阅[为什么 props 复制给 state 会产生 bug](/blog/2018/06/07/you-probably-dont-need-derived-state.html)。 -If your component implements the `getSnapshotBeforeUpdate()` lifecycle (which is rare), the value it returns will be passed as a third "snapshot" parameter to `componentDidUpdate()`. Otherwise this parameter will be undefined. +如果组件实现了 `getSnapshotBeforeUpdate()` 生命周期(不常用),则它的返回值将作为 `componentDidUpdate()` 的第三个参数 “snapshot” 参数传递。否则此参数将为 undefined。 -> Note +> 注意 > -> `componentDidUpdate()` will not be invoked if [`shouldComponentUpdate()`](#shouldcomponentupdate) returns false. +> 如果 [`shouldComponentUpdate()`](#shouldcomponentupdate) 返回值为 false,则不会调用 `componentDidUpdate()`。 * * * @@ -237,15 +237,15 @@ If your component implements the `getSnapshotBeforeUpdate()` lifecycle (which is componentWillUnmount() ``` -`componentWillUnmount()` is invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in `componentDidMount()`. +`componentWillUnmount()` 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在 `componentDidMount()` 中创建的订阅等。 -You **should not call `setState()`** in `componentWillUnmount()` because the component will never be re-rendered. Once a component instance is unmounted, it will never be mounted again. +`componentWillUnmount()` 中**不应调用 `setState()`**,因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。 * * * -### Rarely Used Lifecycle Methods {#rarely-used-lifecycle-methods} +### 不常用的生命周期方法 {#rarely-used-lifecycle-methods} -The methods in this section correspond to uncommon use cases. They're handy once in a while, but most of your components probably don't need any of them. **You can see most of the methods below on [this lifecycle diagram](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/) if you click the "Show less common lifecycles" checkbox at the top of it.** +本节中的生命周期方法并不太常用。它们偶尔会很方便,但是大部分情况下组件可能都不需要它们。你可以在[生命周期图谱](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)中,选择“显示不常用的生命周期”复选框,即可看到下述相关方法。 ### `shouldComponentUpdate()` {#shouldcomponentupdate} @@ -254,17 +254,17 @@ The methods in this section correspond to uncommon use cases. They're handy once shouldComponentUpdate(nextProps, nextState) ``` -Use `shouldComponentUpdate()` to let React know if a component's output is not affected by the current change in state or props. The default behavior is to re-render on every state change, and in the vast majority of cases you should rely on the default behavior. +根据 `shouldComponentUpdate()` 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染。大部分情况下,你应该遵循默认行为。 -`shouldComponentUpdate()` is invoked before rendering when new props or state are being received. Defaults to `true`. This method is not called for the initial render or when `forceUpdate()` is used. +当 props 或 state 发生变化时,`shouldComponentUpdate()` 会在渲染执行之前被调用。返回值默认为 true。首次渲染或使用 `forceUpdate()` 时不会调用该方法。 -This method only exists as a **[performance optimization](/docs/optimizing-performance.html).** Do not rely on it to "prevent" a rendering, as this can lead to bugs. **Consider using the built-in [`PureComponent`](/docs/react-api.html#reactpurecomponent)** instead of writing `shouldComponentUpdate()` by hand. `PureComponent` performs a shallow comparison of props and state, and reduces the chance that you'll skip a necessary update. +此方法仅作为**[性能优化的方式](/docs/optimizing-performance.html)**而存在。不要企图依靠此方法来“阻止”渲染,因为这可能会产生 bug。你应该**考虑使用内置的 [`PureComponent`](/docs/react-api.html#reactpurecomponent) 组件**,而不是手动编写 `shouldComponentUpdate()`。`PureComponent` 会对 props 和 state 进行浅层比较,并减少了跳过必要更新的可能性。 -If you are confident you want to write it by hand, you may compare `this.props` with `nextProps` and `this.state` with `nextState` and return `false` to tell React the update can be skipped. Note that returning `false` does not prevent child components from re-rendering when *their* state changes. +如果你一定要手动编写此函数,可以将 `this.props` 与 `nextProps ` 以及 `this.state` 与`nextState` 进行比较,并返回 `false` 以告知 React 可以跳过更新。请注意,返回 `false` 并不会阻止子组件在 state 更改时重新渲染。 -We do not recommend doing deep equality checks or using `JSON.stringify()` in `shouldComponentUpdate()`. It is very inefficient and will harm performance. +我们不建议在 `shouldComponentUpdate()` 中进行深层比较或使用 `JSON.stringify()`。这样非常影响效率,且会损害性能。 -Currently, if `shouldComponentUpdate()` returns `false`, then [`UNSAFE_componentWillUpdate()`](#unsafe_componentwillupdate), [`render()`](#render), and [`componentDidUpdate()`](#componentdidupdate) will not be invoked. In the future React may treat `shouldComponentUpdate()` as a hint rather than a strict directive, and returning `false` may still result in a re-rendering of the component. +目前,如果 `shouldComponentUpdate()` 返回 `false`,则不会调用 [`UNSAFE_componentWillUpdate()`](#unsafe_componentwillupdate),[`render()`](#render) 和 [`componentDidUpdate()`](#componentdidupdate)。后续版本,React 可能会将 `shouldComponentUpdate` 视为提示而不是严格的指令,并且,当返回 `false` 时,仍可能导致组件重新渲染。 * * * @@ -274,22 +274,22 @@ Currently, if `shouldComponentUpdate()` returns `false`, then [`UNSAFE_component static getDerivedStateFromProps(props, state) ``` -`getDerivedStateFromProps` is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing. +`getDerivedStateFromProps` 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。 -This method exists for [rare use cases](/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state) where the state depends on changes in props over time. For example, it might be handy for implementing a `` component that compares its previous and next children to decide which of them to animate in and out. +此方法适用于[罕见的用例](/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state),即 state 的值在任何时候都取决于 props。例如,实现 `` 组件可能很方便,该组件会比较当前组件与下一组件,以决定针对哪些组件进行转场动画。 -Deriving state leads to verbose code and makes your components difficult to think about. -[Make sure you're familiar with simpler alternatives:](/blog/2018/06/07/you-probably-dont-need-derived-state.html) +派生状态会导致代码冗余,并使组件难以维护。 +[确保你已熟悉这些简单的替代方案:](/blog/2018/06/07/you-probably-dont-need-derived-state.html) -* If you need to **perform a side effect** (for example, data fetching or an animation) in response to a change in props, use [`componentDidUpdate`](#componentdidupdate) lifecycle instead. +* 如果你需要**执行副作用**(例如,数据提取或动画)以响应 props 中的更改,请改用 [`componentDidUpdate`](#componentdidupdate)。 -* If you want to **re-compute some data only when a prop changes**, [use a memoization helper instead](/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization). +* 如果只想在 **prop 更改时重新计算某些数据**,[请使用 memoization helper 代替](/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization)。 -* If you want to **"reset" some state when a prop changes**, consider either making a component [fully controlled](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) or [fully uncontrolled with a `key`](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) instead. +* 如果你想**在 prop 更改时“重置”某些 state**,请考虑使组件[完全受控](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component)或[使用 `key` 使组件完全不受控](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) 代替。 -This method doesn't have access to the component instance. If you'd like, you can reuse some code between `getDerivedStateFromProps()` and the other class methods by extracting pure functions of the component props and state outside the class definition. +此方法无权访问组件实例。如果你需要,可以通过提取组件 props 的纯函数及 class 之外的状态,在`getDerivedStateFromProps()`和其他 class 方法之间重用代码。 -Note that this method is fired on *every* render, regardless of the cause. This is in contrast to `UNSAFE_componentWillReceiveProps`, which only fires when the parent causes a re-render and not as a result of a local `setState`. +请注意,不管原因是什么,都会在*每次*渲染前触发此方法。这与 `UNSAFE_componentWillReceiveProps` 形成对比,后者仅在父组件重新渲染时触发,而不是在内部调用 `setState` 时。 * * * @@ -299,41 +299,41 @@ Note that this method is fired on *every* render, regardless of the cause. This getSnapshotBeforeUpdate(prevProps, prevState) ``` -`getSnapshotBeforeUpdate()` is invoked right before the most recently rendered output is committed to e.g. the DOM. It enables your component to capture some information from the DOM (e.g. scroll position) before it is potentially changed. Any value returned by this lifecycle will be passed as a parameter to `componentDidUpdate()`. +`getSnapshotBeforeUpdate()` 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 `componentDidUpdate()`。 -This use case is not common, but it may occur in UIs like a chat thread that need to handle scroll position in a special way. +此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等。 -A snapshot value (or `null`) should be returned. +应返回 snapshot 的值(或 `null`)。 -For example: +例如: `embed:react-component-reference/get-snapshot-before-update.js` -In the above examples, it is important to read the `scrollHeight` property in `getSnapshotBeforeUpdate` because there may be delays between "render" phase lifecycles (like `render`) and "commit" phase lifecycles (like `getSnapshotBeforeUpdate` and `componentDidUpdate`). +在上述示例中,重点是从 `getSnapshotBeforeUpdate` 读取 `scrollHeight` 属性,因为 “render” 阶段生命周期(如 `render`)和 “commit” 阶段生命周期(如 `getSnapshotBeforeUpdate` 和 `componentDidUpdate`)之间可能存在延迟。 * * * ### Error boundaries {#error-boundaries} -[Error boundaries](/docs/error-boundaries.html) are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them. +[Error boundaries](/docs/error-boundaries.html) 是 React 组件,它会在其子组件树中的任何位置捕获 JavaScript 错误,并记录这些错误,展示降级 UI 而不是崩溃的组件树。Error boundaries 组件会捕获在渲染期间,在生命周期方法以及其整个树的构造函数中发生的错误。 -A class component becomes an error boundary if it defines either (or both) of the lifecycle methods `static getDerivedStateFromError()` or `componentDidCatch()`. Updating state from these lifecycles lets you capture an unhandled JavaScript error in the below tree and display a fallback UI. +如果 class 组件定义了生命周期方法 `static getDerivedStateFromError()` 或 `componentDidCatch()` 中的任何一个(或两者),它就成为了 Error boundaries。通过生命周期更新 state 可让组件捕获树中未处理的 JavaScript 错误并展示降级 UI。 -Only use error boundaries for recovering from unexpected exceptions; **don't try to use them for control flow.** +仅使用 Error boundaries 组件来从意外异常中恢复的情况;**不要将它们用于流程控制。** -For more details, see [*Error Handling in React 16*](/blog/2017/07/26/error-handling-in-react-16.html). +欲了解更多详细信息,请参阅 [*React 16 中的错误处理*](/blog/2017/07/26/error-handling-in-react-16.html)。 -> Note +> 注意 > -> Error boundaries only catch errors in the components **below** them in the tree. An error boundary can’t catch an error within itself. +> Error boundaries 仅捕获组件树中**以下**组件中的错误。但它本身的错误无法捕获。 ### `static getDerivedStateFromError()` {#static-getderivedstatefromerror} ```javascript static getDerivedStateFromError(error) ``` -This lifecycle is invoked after an error has been thrown by a descendant component. -It receives the error that was thrown as a parameter and should return a value to update state. +此生命周期会在后代组件抛出错误后被调用。 +它将抛出的错误作为参数,并返回一个值以更新 state ```js{7-10,13-16} class ErrorBoundary extends React.Component { @@ -343,13 +343,13 @@ class ErrorBoundary extends React.Component { } static getDerivedStateFromError(error) { - // Update state so the next render will show the fallback UI. + // 更新 state 使下一次渲染可以显降级 UI return { hasError: true }; } render() { if (this.state.hasError) { - // You can render any custom fallback UI + // 你可以渲染任何自定义的降级 UI return

Something went wrong.

; } @@ -358,10 +358,10 @@ class ErrorBoundary extends React.Component { } ``` -> Note +> 注意 > -> `getDerivedStateFromError()` is called during the "render" phase, so side-effects are not permitted. -For those use cases, use `componentDidCatch()` instead. +> `getDerivedStateFromError()` 会在`渲染`阶段调用,因此不允许出现副作用。 +如遇此类情况,请改用 `componentDidCatch()`。 * * * @@ -371,15 +371,15 @@ For those use cases, use `componentDidCatch()` instead. componentDidCatch(error, info) ``` -This lifecycle is invoked after an error has been thrown by a descendant component. -It receives two parameters: +此生命周期在后代组件抛出错误后被调用。 +它接收两个参数: -1. `error` - The error that was thrown. -2. `info` - An object with a `componentStack` key containing [information about which component threw the error](/docs/error-boundaries.html#component-stack-traces). +1. `error` —— 抛出的错误。 +2. `info` —— 带有 `componentStack` key 的对象,其中包含[有关组件引发错误的栈信息](/docs/error-boundaries.html#component-stack-traces)。 -`componentDidCatch()` is called during the "commit" phase, so side-effects are permitted. -It should be used for things like logging errors: +`componentDidCatch()` 会在“提交”阶段被调用,因此允许执行副作用。 +它应该用于记录错误之类的情况: ```js{12-19} class ErrorBoundary extends React.Component { @@ -389,12 +389,12 @@ class ErrorBoundary extends React.Component { } static getDerivedStateFromError(error) { - // Update state so the next render will show the fallback UI. + // 更新 state 使下一次渲染可以显示降级 UI return { hasError: true }; } componentDidCatch(error, info) { - // Example "componentStack": + // "组件堆栈" 例子: // in ComponentThatThrows (created by App) // in ErrorBoundary (created by App) // in div (created by App) @@ -404,7 +404,7 @@ class ErrorBoundary extends React.Component { render() { if (this.state.hasError) { - // You can render any custom fallback UI + // 你可以渲染任何自定义的降级 UI return

Something went wrong.

; } @@ -413,16 +413,16 @@ class ErrorBoundary extends React.Component { } ``` -> Note +> 注意 > -> In the event of an error, you can render a fallback UI with `componentDidCatch()` by calling `setState`, but this will be deprecated in a future release. -> Use `static getDerivedStateFromError()` to handle fallback rendering instead. +> 如果发生错误,你可以通过调用 `setState` 使用 `componentDidCatch()` 渲染降级 UI,但在未来的版本中将不推荐这样做。 +> 可以使用静态 `getDerivedStateFromError()` 来处理降级渲染。 * * * -### Legacy Lifecycle Methods {#legacy-lifecycle-methods} +### 过时的生命周期方法 {#legacy-lifecycle-methods} -The lifecycle methods below are marked as "legacy". They still work, but we don't recommend using them in the new code. You can learn more about migrating away from legacy lifecycle methods in [this blog post](/blog/2018/03/27/update-on-async-rendering.html). +以下生命周期方法标记为“过时”。这些方法仍然有效,但不建议在新代码中使用它们。参阅此[博客文章](/blog/2018/03/27/update-on-async-rendering.html)以了解更多有关迁移旧版生命周期方法的信息。 ### `UNSAFE_componentWillMount()` {#unsafe_componentwillmount} @@ -430,15 +430,15 @@ The lifecycle methods below are marked as "legacy". They still work, but we don' UNSAFE_componentWillMount() ``` -> Note +> 注意 > -> This lifecycle was previously named `componentWillMount`. That name will continue to work until version 17. Use the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components. +> 此生命周期之前名为 `componentWillMount`。该名称将继续使用至 React 17。可以使用 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 自动更新你的组件。 -`UNSAFE_componentWillMount()` is invoked just before mounting occurs. It is called before `render()`, therefore calling `setState()` synchronously in this method will not trigger an extra rendering. Generally, we recommend using the `constructor()` instead for initializing state. +`UNSAFE_componentWillMount()` 在挂载之前被调用。它在 `render()` 之前调用,因此在此方法中同步调用 `setState()` 不会触发额外渲染。通常,我们建议使用 `constructor()` 来初始化 state。 -Avoid introducing any side-effects or subscriptions in this method. For those use cases, use `componentDidMount()` instead. +避免在此方法中引入任何副作用或订阅。如遇此种情况,请改用 `componentDidMoun -This is the only lifecycle method called on server rendering. +此方法是服务端渲染唯一会调用的生命周期函数。 * * * @@ -448,25 +448,25 @@ This is the only lifecycle method called on server rendering. UNSAFE_componentWillReceiveProps(nextProps) ``` -> Note +> 注意 > -> This lifecycle was previously named `componentWillReceiveProps`. That name will continue to work until version 17. Use the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components. +> 此生命周期之前名为 `componentWillReceiveProps`。该名称将继续使用至 React 17。可以使用 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 自动更新你的组件。 -> Note: +> 注意: > -> Using this lifecycle method often leads to bugs and inconsistencies +> 使用此生命周期方法通常会出现 bug 和不一致性: > -> * If you need to **perform a side effect** (for example, data fetching or an animation) in response to a change in props, use [`componentDidUpdate`](#componentdidupdate) lifecycle instead. -> * If you used `componentWillReceiveProps` for **re-computing some data only when a prop changes**, [use a memoization helper instead](/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization). -> * If you used `componentWillReceiveProps` to **"reset" some state when a prop changes**, consider either making a component [fully controlled](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) or [fully uncontrolled with a `key`](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) instead. +> * 如果你需要**执行副作用**(例如,数据提取或动画)以响应 props 中的更改,请改用 [`componentDidUpdate`](#componentdidupdate) 生命周期。 +> * 如果你使用 `componentWillReceiveProps` **仅在 prop 更改时重新计算某些数据**,请[使用 memoization helper 代替](/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization)。 +> * 如果你使用 `componentWillReceiveProps` 是为了**在 prop 更改时“重置”某些 state**,请考虑使组件[完全受控](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component)或[使用 `key` 使组件完全不受控](/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) 代替。 > -> For other use cases, [follow the recommendations in this blog post about derived state](/blog/2018/06/07/you-probably-dont-need-derived-state.html). +> 对于其他使用场景,[请遵循此博客文章中有关派生状态的建议](/blog/2018/06/07/you-probably-dont-need-derived-state.html)。 -`UNSAFE_componentWillReceiveProps()` is invoked before a mounted component receives new props. If you need to update the state in response to prop changes (for example, to reset it), you may compare `this.props` and `nextProps` and perform state transitions using `this.setState()` in this method. +`UNSAFE_componentWillReceiveProps()` 会在已挂载的组件接收新的 props 之前被调用。如果你需要更新状态以响应 prop 更改(例如,重置它),你可以比较 `this.props` 和 `nextProps` 并在此方法中使用 `this.setState()` 执行 state 转换。 -Note that if a parent component causes your component to re-render, this method will be called even if props have not changed. Make sure to compare the current and next values if you only want to handle changes. +请注意,如果父组件导致组件重新渲染,即使 props 没有更改,也会调用此方法。如果只想处理更改,请确保进行当前值与变更值的比较。 -React doesn't call `UNSAFE_componentWillReceiveProps()` with initial props during [mounting](#mounting). It only calls this method if some of component's props may update. Calling `this.setState()` generally doesn't trigger `UNSAFE_componentWillReceiveProps()`. +在[挂载](#mounting)过程中,React 不会针对初始 props 调用 `UNSAFE_componentWillReceiveProps()`。组件只会在组件的 props 更新时调用此方法。调用 `this.setState()` 通常不会触发 `UNSAFE_componentWillReceiveProps()`。 * * * @@ -476,27 +476,27 @@ React doesn't call `UNSAFE_componentWillReceiveProps()` with initial props durin UNSAFE_componentWillUpdate(nextProps, nextState) ``` -> Note +> 注意 > -> This lifecycle was previously named `componentWillUpdate`. That name will continue to work until version 17. Use the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components. +> 此生命周期之前名为 `componentWillUpdate`。该名称将继续使用至 React 17。可以使用 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 自动更新你的组件。 -`UNSAFE_componentWillUpdate()` is invoked just before rendering when new props or state are being received. Use this as an opportunity to perform preparation before an update occurs. This method is not called for the initial render. +当组件收到新的 props 或 state 时,会在渲染之前调用 `UNSAFE_componentWillUpdate()`。使用此作为在更新发生之前执行准备更新的机会。初始渲染不会调用此方法。 -Note that you cannot call `this.setState()` here; nor should you do anything else (e.g. dispatch a Redux action) that would trigger an update to a React component before `UNSAFE_componentWillUpdate()` returns. +注意,你不能此方法中调用 `this.setState()`;在 `UNSAFE_componentWillUpdate()` 返回之前,你也不应该执行任何其他操作(例如,dispatch Redux 的 action)触发对 React 组件的更新 -Typically, this method can be replaced by `componentDidUpdate()`. If you were reading from the DOM in this method (e.g. to save a scroll position), you can move that logic to `getSnapshotBeforeUpdate()`. +通常,此方法可以替换为 `componentDidUpdate()`。如果你在此方法中读取 DOM 信息(例如,为了保存滚动位置),则可以将此逻辑移至 `getSnapshotBeforeUpdate()` 中。 -> Note +> 注意 > -> `UNSAFE_componentWillUpdate()` will not be invoked if [`shouldComponentUpdate()`](#shouldcomponentupdate) returns false. +> 如果 `shouldComponentUpdate()` 返回 false,则不会调用 `UNSAFE_componentWillUpdate()`。 * * * -## Other APIs {#other-apis-1} +## 其他 API {#other-apis-1} -Unlike the lifecycle methods above (which React calls for you), the methods below are the methods *you* can call from your components. +不同于上述生命周期方法(React 主动调用),以下方法是你可以在组件中调用的方法。 -There are just two of them: `setState()` and `forceUpdate()`. +只有两个方法:`setState()` 和 `forceUpdate()`。 ### `setState()` {#setstate} @@ -504,21 +504,21 @@ There are just two of them: `setState()` and `forceUpdate()`. setState(updater[, callback]) ``` -`setState()` enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state. This is the primary method you use to update the user interface in response to event handlers and server responses. +`setState()` 将对组件 state 的更改排入队列,并通知 React 需要使用更新后的 state 重新渲染此组件及其子组件。这是用于更新用户界面以响应事件处理器和处理服务器数据的主要方式 -Think of `setState()` as a *request* rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately. +将 `setState()` 视为*请求*而不是立即更新组件的命令。为了更好的感知性能,React 会延迟调用它,然后通过一次传递更新多个组件。React 并不会保证 state 的变更会立即生效。 -`setState()` does not always immediately update the component. It may batch or defer the update until later. This makes reading `this.state` right after calling `setState()` a potential pitfall. Instead, use `componentDidUpdate` or a `setState` callback (`setState(updater, callback)`), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the `updater` argument below. +`setState()` 并不总是立即更新组件。它会批量推迟更新。这使得在调用 `setState()` 后立即读取 `this.state` 成为了隐患。为了消除隐患,请使用 `componentDidUpdate` 或者 `setState` 的回调函数(`setState(updater, callback)`),这两种方式都可以保证在应用更新后触发。如需基于之前的 state 来设置当前的 state,请阅读下述关于参数 `updater` 的内容。 -`setState()` will always lead to a re-render unless `shouldComponentUpdate()` returns `false`. If mutable objects are being used and conditional rendering logic cannot be implemented in `shouldComponentUpdate()`, calling `setState()` only when the new state differs from the previous state will avoid unnecessary re-renders. +除非 `shouldComponentUpdate()` 返回 `false`,否则 `setState()` 将始终执行重新渲染操作。如果可变对象被使用,且无法在 `shouldComponentUpdate()` 中实现条件渲染,那么仅在新旧状态不一时调用 `setState()`可以避免不必要的重新渲染 -The first argument is an `updater` function with the signature: +参数一为带有形式参数的 `updater` 函数: ```javascript (state, props) => stateChange ``` -`state` is a reference to the component state at the time the change is being applied. It should not be directly mutated. Instead, changes should be represented by building a new object based on the input from `state` and `props`. For instance, suppose we wanted to increment a value in state by `props.step`: +`state` 是对应用变化时组件状态的引用。当然,它不应直接被修改。你应该使用基于 `state` 和 `props` 构建的新对象来表示变化。例如,假设我们想根据 `props.step` 来增加 state: ```javascript this.setState((state, props) => { @@ -526,23 +526,23 @@ this.setState((state, props) => { }); ``` -Both `state` and `props` received by the updater function are guaranteed to be up-to-date. The output of the updater is shallowly merged with `state`. +updater 函数中接收的 `state` 和 `props` 都保证为最新。updater 的返回值会与 `state` 进行浅合并。 -The second parameter to `setState()` is an optional callback function that will be executed once `setState` is completed and the component is re-rendered. Generally we recommend using `componentDidUpdate()` for such logic instead. +`setState()` 的第二个参数为可选的回调函数,它将在 `setState` 完成合并并重新渲染组件后执行。通常,我们建议使用 `componentDidUpdate()` 来代替此方式。 -You may optionally pass an object as the first argument to `setState()` instead of a function: +`setState()` 的第一个参数除了接受函数外,还可以接受对象类型: ```javascript setState(stateChange[, callback]) ``` -This performs a shallow merge of `stateChange` into the new state, e.g., to adjust a shopping cart item quantity: +`stateChange` 会将传入的对象浅层合并到新的 state 中,例如,调整购物车商品数: ```javascript this.setState({quantity: 2}) ``` -This form of `setState()` is also asynchronous, and multiple calls during the same cycle may be batched together. For example, if you attempt to increment an item quantity more than once in the same cycle, that will result in the equivalent of: +这种形式的 `setState()` 也是异步的,并且在同一周期内会对多个 `setState` 进行批处理。例如,如果在同一周期内多次设置商品数量增加,则相当于: ```javaScript Object.assign( @@ -553,7 +553,7 @@ Object.assign( ) ``` -Subsequent calls will override values from previous calls in the same cycle, so the quantity will only be incremented once. If the next state depends on the current state, we recommend using the updater function form, instead: +后调用的 `setState()` 将覆盖同一周期内先调用 `setState` 的值,因此商品数仅增加一次。如果后续状态取决于当前状态,我们建议使用 updater 函数的形式代替: ```js this.setState((state) => { @@ -561,11 +561,11 @@ this.setState((state) => { }); ``` -For more detail, see: +有关更多详细信息,请参阅: -* [State and Lifecycle guide](/docs/state-and-lifecycle.html) -* [In depth: When and why are `setState()` calls batched?](https://stackoverflow.com/a/48610973/458193) -* [In depth: Why isn't `this.state` updated immediately?](https://github.com/facebook/react/issues/11527#issuecomment-360199710) +* [State 和生命周期指南](/docs/state-and-lifecycle.html) +* [深入学习:何时以及为什么 `setState()` 会批量执行?](https://stackoverflow.com/a/48610973/458193) +* [深入:为什么不直接更新 `this.state`?](https://github.com/facebook/react/issues/11527#issuecomment-360199710) * * * @@ -575,19 +575,19 @@ For more detail, see: component.forceUpdate(callback) ``` -By default, when your component's state or props change, your component will re-render. If your `render()` method depends on some other data, you can tell React that the component needs re-rendering by calling `forceUpdate()`. +默认情况下,当组件的 state 或 props 发生变化时,组件将重新渲染。如果 `render()` 方法依赖于其他数据,则可以调用 `forceUpdate()` 强制让组件重新渲染。 -Calling `forceUpdate()` will cause `render()` to be called on the component, skipping `shouldComponentUpdate()`. This will trigger the normal lifecycle methods for child components, including the `shouldComponentUpdate()` method of each child. React will still only update the DOM if the markup changes. +调用 `forceUpdate()` 将致使组件调用 `render()` 方法,此操作会跳过该组件的 `shouldComponentUpdate()`。但其子组件会触发正常的生命周期方法,包括 `shouldComponentUpdate()` 方法。如果标记发生变化,React 仍将只更新 DOM。 -Normally you should try to avoid all uses of `forceUpdate()` and only read from `this.props` and `this.state` in `render()`. +通常你应该避免使用 `forceUpdate()`,尽量在 `render()` 只使用 `this.props` 和 `this.state` * * * -## Class Properties {#class-properties-1} +## Class 属性 {#class-properties-1} ### `defaultProps` {#defaultprops} -`defaultProps` can be defined as a property on the component class itself, to set the default props for the class. This is used for undefined props, but not for null props. For example: +`defaultProps` 可以为 Class 组件添加默认 props。这一般用于 props 未赋值,但又不能为 null 的情况。例如: ```js class CustomButton extends React.Component { @@ -599,19 +599,19 @@ CustomButton.defaultProps = { }; ``` -If `props.color` is not provided, it will be set by default to `'blue'`: +如果未提供 `props.color`,则默认设置为 `'blue'` ```js render() { - return ; // props.color will be set to blue + return ; // props.color 将设置为 'blue' } ``` -If `props.color` is set to null, it will remain null: +如果 `props.color` 被设置为 `null`,则它将保持为 `null` ```js render() { - return ; // props.color will remain null + return ; // props.color 将保持是 null } ``` @@ -619,24 +619,24 @@ If `props.color` is set to null, it will remain null: ### `displayName` {#displayname} -The `displayName` string is used in debugging messages. Usually, you don't need to set it explicitly because it's inferred from the name of the function or class that defines the component. You might want to set it explicitly if you want to display a different name for debugging purposes or when you create a higher-order component, see [Wrap the Display Name for Easy Debugging](/docs/higher-order-components.html#convention-wrap-the-display-name-for-easy-debugging) for details. +`displayName` 字符串多用于调试消息。通常,你不需要设置它,因为它可以根据函数组件或 class 组件的名称推断出来。如果调试时需要显示不同的名称或创建高阶组件,请参阅[使用 displayname 轻松进行调试](/docs/higher-order-components.html#convention-wrap-the-display-name-for-easy-debugging)了解更多。 * * * -## Instance Properties {#instance-properties-1} +## 实例属性 {#instance-properties-1} ### `props` {#props} -`this.props` contains the props that were defined by the caller of this component. See [Components and Props](/docs/components-and-props.html) for an introduction to props. +`this.props` 包括被该组件调用者定义的 props。欲了解 props 的详细介绍,请参阅[组件 & Props][组件和props](/docs/components-and-props.html)。 -In particular, `this.props.children` is a special prop, typically defined by the child tags in the JSX expression rather than in the tag itself. +需特别注意,`this.props.children` 是一个特殊的 prop,通常由 JSX 表达式中的子组件组成,而不是由组件本身定义。 ### `state` {#state} -The state contains data specific to this component that may change over time. The state is user-defined, and it should be a plain JavaScript object. +组件中的 state 包含了随时可能发生变化的数据。state 由用户自定义,它是一个普通 JavaScript 对象。 -If some value isn't used for rendering or data flow (for example, a timer ID), you don't have to put it in the state. Such values can be defined as fields on the component instance. +如果某些值未用于渲染或数据流(例如,计时器 ID),则不必将其设置为 state。此类值可以在组件实例上定义。 -See [State and Lifecycle](/docs/state-and-lifecycle.html) for more information about the state. +欲了解关于 state 的更多信息,请参阅 [State & 生命周期](/docs/state-and-lifecycle.html)。 -Never mutate `this.state` directly, as calling `setState()` afterwards may replace the mutation you made. Treat `this.state` as if it were immutable. +永远不要直接改变 `this.state`,因为后续调用的 `setState()` 可能会替换掉你的改变。请把 `this.state` 看作是不可变的。 diff --git a/examples/react-component-reference/get-snapshot-before-update.js b/examples/react-component-reference/get-snapshot-before-update.js index cf1fb23351..05c082aa65 100644 --- a/examples/react-component-reference/get-snapshot-before-update.js +++ b/examples/react-component-reference/get-snapshot-before-update.js @@ -5,8 +5,8 @@ class ScrollingList extends React.Component { } getSnapshotBeforeUpdate(prevProps, prevState) { - // Are we adding new items to the list? - // Capture the scroll position so we can adjust scroll later. + // 我们是否在 list 中添加新的 items ? + // 捕获滚动​​位置以便我们稍后调整滚动位置。 if (prevProps.list.length < this.props.list.length) { const list = this.listRef.current; return list.scrollHeight - list.scrollTop; @@ -15,9 +15,9 @@ class ScrollingList extends React.Component { } componentDidUpdate(prevProps, prevState, snapshot) { - // If we have a snapshot value, we've just added new items. - // Adjust scroll so these new items don't push the old ones out of view. - // (snapshot here is the value returned from getSnapshotBeforeUpdate) + // 如果我们 snapshot 有值,说明我们刚刚添加了新的 items, + // 调整滚动位置使得这些新 items 不会将旧的 items 推出视图。 + //(这里的 snapshot 是 getSnapshotBeforeUpdate 的返回值) if (snapshot !== null) { const list = this.listRef.current; list.scrollTop = list.scrollHeight - snapshot;