From 017405093d0d491823f935c85c3627d13383877e Mon Sep 17 00:00:00 2001 From: Tosuke <1848228664@qq.com> Date: Sun, 2 Jul 2023 22:45:13 +0800 Subject: [PATCH 01/13] docs(cn): docs(cn): translate api/component into Chinese --- src/content/reference/react/Component.md | 632 +++++++++++------------ 1 file changed, 316 insertions(+), 316 deletions(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index 006ade5d8d..b2d93c7781 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -4,13 +4,13 @@ title: Component -We recommend defining components as functions instead of classes. [See how to migrate.](#alternatives) +我们建议将组件定义为函数而不是类。[了解如何迁移](#alternatives) -`Component` is the base class for the React components defined as [JavaScript classes.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) Class components are still supported by React, but we don't recommend using them in new code. +`Component` 是被定义为 [JavaScript 类](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) 的 React 基类,类组件仍然被 React 支持,但我们不建议在新代码中使用它们。 ```js class Greeting extends Component { @@ -26,11 +26,11 @@ class Greeting extends Component { --- -## Reference {/*reference*/} +## 参考 {/*reference*/} ### `Component` {/*component*/} -To define a React component as a class, extend the built-in `Component` class and define a [`render` method:](#render) +要想将React组件定义为一个类,你需要扩展内置的 `Component` 类并定义一个 [`render` 方法](#render): ```js import { Component } from 'react'; @@ -42,17 +42,17 @@ class Greeting extends Component { } ``` -Only the `render` method is required, other methods are optional. +只有 `render` 方法是必要的,其他方法是可选的。 -[See more examples below.](#usage) +[查看以下的更多实例](#usage) --- ### `context` {/*context*/} -The [context](/learn/passing-data-deeply-with-context) of a class component is available as `this.context`. It is only available if you specify *which* context you want to receive using [`static contextType`](#static-contexttype) (modern) or [`static contextTypes`](#static-contexttypes) (deprecated). +一个类组件的 [context](/learn/passing-data-deeply-with-context) 可以通过使用 `this.context` 来实现。 只有当你使用 [`static contextType`](#static-contexttype) (更新的)或者 [`static contextTypes`](#static-contexttypes) (已被废弃) 来特别指定你想要接受 **哪一个** context 时它才会有效。 -A class component can only read one context at a time. +类组件一次只能读取一个context。 ```js {2,5} class Button extends Component { @@ -73,9 +73,9 @@ class Button extends Component { -Reading `this.context` in class components is equivalent to [`useContext`](/reference/react/useContext) in function components. +在类组件中读取 `this.context` 等同于在函数式组件中使用的 [`useContext`](/reference/react/useContext) 。 -[See how to migrate.](#migrating-a-component-with-context-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-context-from-a-class-to-a-function) @@ -83,7 +83,7 @@ Reading `this.context` in class components is equivalent to [`useContext`](/refe ### `props` {/*props*/} -The props passed to a class component are available as `this.props`. +传递给类组件的 props 的有效形式为 `this.props` 。 ```js {3} class Greeting extends Component { @@ -97,9 +97,9 @@ class Greeting extends Component { -Reading `this.props` in class components is equivalent to [declaring props](/learn/passing-props-to-a-component#step-2-read-props-inside-the-child-component) in function components. +在类组件中读取 `this.props` 等同于在函数式组件中使用的 [declaring props](/learn/passing-props-to-a-component#step-2-read-props-inside-the-child-component) 。 -[See how to migrate.](#migrating-a-simple-component-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-simple-component-from-a-class-to-a-function) @@ -109,17 +109,17 @@ Reading `this.props` in class components is equivalent to [declaring props](/lea -This API will be removed in a future major version of React. [Use `createRef` instead.](/reference/react/createRef) +这个API将在未来React的主版本中被移除。 [使用 `createRef` 来代替](/reference/react/createRef)。 -Lets you access [legacy string refs](https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs) for this component. +允许你获取此组件的 [legacy string refs](https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs) --- ### `state` {/*state*/} -The state of a class component is available as `this.state`. The `state` field must be an object. Do not mutate the state directly. If you wish to change the state, call `setState` with the new state. +使用 `this.state` 来访问一个类组件的 state 。 `state` 字段必须是一个对象。请不要直接改变 state 的值。如果你希望改变 state ,使用新的 state 来调用 `setState` 函数。 ```js {2-4,7-9,18} class Counter extends Component { @@ -148,9 +148,9 @@ class Counter extends Component { -Defining `state` in class components is equivalent to calling [`useState`](/reference/react/useState) in function components. +在类组件中定义 `state` 等同于在函数式组件中通过调用 [`useState`](/reference/react/useState) 函数所创造的 state 。 -[See how to migrate.](#migrating-a-component-with-state-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function) @@ -158,7 +158,7 @@ Defining `state` in class components is equivalent to calling [`useState`](/refe ### `constructor(props)` {/*constructor*/} -The [constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor) runs before your class component *mounts* (gets added to the screen). Typically, a constructor is only used for two purposes in React. It lets you declare state and [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind) your class methods to the class instance: +[constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor) 在你的类组件 **挂载**(添加到屏幕上)之前运行,一般来说,在 React 中 constructor 仅用于两个目的。它可以让你来声明 state 以及将你的类方法 [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind) 到你的类实例上。 ```js {2-6} class Counter extends Component { @@ -173,7 +173,7 @@ class Counter extends Component { } ``` -If you use modern JavaScript syntax, constructors are rarely needed. Instead, you can rewrite this code above using the [public class field syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields) which is supported both by modern browsers and tools like [Babel:](https://babeljs.io/) +如果你使用更新的 JavaScript 语法的话,那么很少需要使用到 constructors 。相反,你可以使用现代浏览器和像 [Babel](https://babeljs.io/) 这样的工具都支持的[公有类字段语法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields)来重写上面的代码。 ```js {2,4} class Counter extends Component { @@ -184,31 +184,31 @@ class Counter extends Component { } ``` -A constructor should not contain any side effects or subscriptions. +constructor 不应该包含任何额外作用或者监听相关。 -#### Parameters {/*constructor-parameters*/} +#### 参数 {/*constructor-parameters*/} -* `props`: The component's initial props. +* `props`: 组件初始的 props 。 -#### Returns {/*constructor-returns*/} +#### 返回值 {/*constructor-returns*/} -`constructor` should not return anything. +`constructor` 不应该返回任何东西。 -#### Caveats {/*constructor-caveats*/} +#### 说明 {/*constructor-caveats*/} -* Do not run any side effects or subscriptions in the constructor. Instead, use [`componentDidMount`](#componentdidmount) for that. +* 不要在 constructor 中运行任何任额外作用或者监听相关的代码。相反,我们使用 [`componentDidMount`](#componentdidmount) 来解决这个问题。 -* Inside a constructor, you need to call `super(props)` before any other statement. If you don't do that, `this.props` will be `undefined` while the constructor runs, which can be confusing and cause bugs. +* 在 constructor 中,你需要在其他声明之前调用 `super(props)` 。如果你不这样做,当 constructor 运行时 `this.props` 就会为 `undefined` , 这可能会让人迷惑并且导致错误。 + +* Constructor 是唯一一个你能直接赋值 [`this.state`](#state) 的地方。 在其余所有方法中,你需要使用 [`this.setState()`](#setstate) 来代替。不要使用在 constructor 中使用 `setState` 。 -* Constructor is the only place where you can assign [`this.state`](#state) directly. In all other methods, you need to use [`this.setState()`](#setstate) instead. Do not call `setState` in the constructor. +* 当你使用 [服务端渲染](/reference/react-dom/server) 时, constructor 也将在服务端运行,紧接着是 [`render`](#render) 方法。 然而,像是 `componentDidMount` 或者 `componentWillUnmount` 这样的生命周期方法将不会在服务端运行。 -* When you use [server rendering,](/reference/react-dom/server) the constructor will run on the server too, followed by the [`render`](#render) method. However, lifecycle methods like `componentDidMount` or `componentWillUnmount` will not run on the server. - -* When [Strict Mode](/reference/react/StrictMode) is on, React will call `constructor` twice in development and then throw away one of the instances. This helps you notice the accidental side effects that need to be moved out of the `constructor`. +* 当 [严格模式](/reference/react/StrictMode) 打开时, React 将会在开发过程中调用两次 `constructor` 然后丢弃其中的一个实例。这有助于你注意到需要从 `constructor` 中移出的意外副作用。 -There is no exact equivalent for `constructor` in function components. To declare state in a function component, call [`useState`.](/reference/react/useState) To avoid recalculating the initial state, [pass a function to `useState`.](/reference/react/useState#avoiding-recreating-the-initial-state) +在函数式组件中没有与 `constructor` 完全相同的构造函数。 要在函数式组件中声明 state 请调用 [`useState`](/reference/react/useState) 来避免重复计算 state 的初始状态。[传递一个函数给 `useState`](/reference/react/useState#avoiding-recreating-the-initial-state)。 @@ -216,31 +216,31 @@ There is no exact equivalent for `constructor` in function components. To declar ### `componentDidCatch(error, info)` {/*componentdidcatch*/} -If you define `componentDidCatch`, React will call it when some child component (including distant children) throws an error during rendering. This lets you log that error to an error reporting service in production. +如果你定义了 `componentDidCatch` ,那么当某些子组件(包括远程子组件)在渲染过程中抛出错误时React将调用它。这使得你可以在生产中将该错误记录到错误报告服务中。 -Typically, it is used together with [`static getDerivedStateFromError`](#static-getderivedstatefromerror) which lets you update state in response to an error and display an error message to the user. A component with these methods is called an *error boundary.* +一般来说,它与 [`static getDerivedStateFromError`](#static-getderivedstatefromerror) 一起使用,这样做允许你更新状态以响应错误并向用户显示错误消息。具有这些方法的组件称为 **错误边界** 。 -[See an example.](#catching-rendering-errors-with-an-error-boundary) +[查看示例](#catching-rendering-errors-with-an-error-boundary) -#### Parameters {/*componentdidcatch-parameters*/} +#### 参数 {/*componentdidcatch-parameters*/} -* `error`: The error that was thrown. In practice, it will usually be an instance of [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) but this is not guaranteed because JavaScript allows to [`throw`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) any value, including strings or even `null`. +* `error`: 抛出的错误。实际上,它通常会是一个 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,不过这并不能保证,因为 JavaScript 允许 [`throw`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 所有的值,包括字符串甚至是 `null` 。 -* `info`: An object containing additional information about the error. Its `componentStack` field contains a stack trace with the component that threw, as well as the names and source locations of all its parent components. In production, the component names will be minified. If you set up production error reporting, you can decode the component stack using sourcemaps the same way as you would do for regular JavaScript error stacks. +* `info`: 一个包含有关错误的附加信息的对象。 它的 `componentStack` 字段包含一个堆栈跟踪,其中包含抛出的组件,以及其所有父组件的名称和源位置。在生产中,组件名称将被缩小。如果你设置了生产错误报告,则可以使用源映射来解码组件堆栈,就像处理常规 JavaScript 错误堆栈一样。 -#### Returns {/*componentdidcatch-returns*/} +#### 返回值 {/*componentdidcatch-returns*/} -`componentDidCatch` should not return anything. +`componentDidCatch` 不应该返回任何值。 -#### Caveats {/*componentdidcatch-caveats*/} +#### 说明 {/*componentdidcatch-caveats*/} -* In the past, it was common to call `setState` inside `componentDidCatch` in order to update the UI and display the fallback error message. This is deprecated in favor of defining [`static getDerivedStateFromError`.](#static-getderivedstatefromerror) +* 在以前, 经常在 `componentDidCatch` 中使用 `setState` 来更新UI以及显示回退错误消息。这已被废弃,有利于定义 [`static getDerivedStateFromError`.](#static-getderivedstatefromerror) 。 -* Production and development builds of React slightly differ in the way `componentDidCatch` handles errors. In development, the errors will bubble up to `window`, which means that any `window.onerror` or `window.addEventListener('error', callback)` will intercept the errors that have been caught by `componentDidCatch`. In production, instead, the errors will not bubble up, which means any ancestor error handler will only receive errors not explicitly caught by `componentDidCatch`. +* React 的生产和开发版本在 `componentDidCatch` 处理错误的方式有所不同,在开发环境下,错误将冒泡至 `window` ,这意味着任何 `window.onerror` 或者 `window.addEventListener('error', callback)` 都将拦截被 `componentDidCatch` 所捕获到的错误。在生产环境下,相反,错误并不会冒泡, 这意味着任何祖先级的错误处理器都只会接收到被 `componentDidCatch` 捕获的非显式错误。 -There is no direct equivalent for `componentDidCatch` in function components yet. If you'd like to avoid creating class components, write a single `ErrorBoundary` component like above and use it throughout your app. Alternatively, you can use the [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) package which does that for you. +在函数组件中目前还没有直接等价的 `componentDidCatch` 。如果你想要避免创建类组件,那么可以单独写一个像上面一样的 `ErrorBoundary` 并在整个应用中使用它。 又或者,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包,它可以完成同样的工作。 @@ -248,9 +248,9 @@ There is no direct equivalent for `componentDidCatch` in function components yet ### `componentDidMount()` {/*componentdidmount*/} -If you define the `componentDidMount` method, React will call it when your component is added *(mounted)* to the screen. This is a common place to start data fetching, set up subscriptions, or manipulate the DOM nodes. +如果你定义了 `componentDidMount` 方法, React 将会在你的组件添加上屏幕 **(mounted)** 时调用它。这是开始数据获取、设置监听或操作DOM节点的常见位置。 -If you implement `componentDidMount`, you usually need to implement other lifecycle methods to avoid bugs. For example, if `componentDidMount` reads some state or props, you also have to implement [`componentDidUpdate`](#componentdidupdate) to handle their changes, and [`componentWillUnmount`](#componentwillunmount) to clean up whatever `componentDidMount` was doing. +如果你要执行 `componentDidMount` ,你通常需要设置一些其他的生命周期函数来避免出错。例如,如果 `componentDidMount` 读取一些 state 或者 props ,你还必须要设置 [`componentDidUpdate`](#componentdidupdate) 来处理它们的更改, 以及设置 [`componentWillUnmount`](#componentwillunmount) 来清理 `componentDidMount` 所产生的作用。 ```js {6-8} class ChatRoom extends Component { @@ -280,27 +280,27 @@ class ChatRoom extends Component { } ``` -[See more examples.](#adding-lifecycle-methods-to-a-class-component) +[查看更多实例](#adding-lifecycle-methods-to-a-class-component) -#### Parameters {/*componentdidmount-parameters*/} +#### 参数 {/*componentdidmount-parameters*/} -`componentDidMount` does not take any parameters. +`componentDidMount` 不需要任何参数。 -#### Returns {/*componentdidmount-returns*/} +#### 返回值 {/*componentdidmount-returns*/} -`componentDidMount` should not return anything. +`componentDidMount` 不应该返回任何值。 -#### Caveats {/*componentdidmount-caveats*/} +#### 说明 {/*componentdidmount-caveats*/} -- When [Strict Mode](/reference/react/StrictMode) is on, in development React will call `componentDidMount`, then immediately call [`componentWillUnmount`,](#componentwillunmount) and then call `componentDidMount` again. This helps you notice if you forgot to implement `componentWillUnmount` or if its logic doesn't fully "mirror" what `componentDidMount` does. +- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发环境中 React 会调用 `componentDidMount`,然后会立刻调用 [`componentWillUnmount`,](#componentwillunmount) 接着再次调用 `componentDidMount` 。 这将帮助你注意到你是否忘记设置 `componentWillUnmount` 或者它的逻辑是否完全覆盖到 `componentDidMount` 的功能。 -- Although you may call [`setState`](#setstate) immediately in `componentDidMount`, it's best to avoid that when you can. It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the [`render`](#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`](#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`](#setstate) ,不过最好避免这样做。 这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。 这确认了在这种情况下即使 [`render`](#render) 被调用了两次, 用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下, 你应该能在[`constructor`](#constructor)中设置初始的 state 。 但是,对于模态和工具提示等情况,当你需要在呈现依赖于其大小或位置的内容之前测量 DOM 节点时,它可能是必要的。 -For many use cases, defining `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` together in class components is equivalent to calling [`useEffect`](/reference/react/useEffect) in function components. In the rare cases where it's important for the code to run before browser paint, [`useLayoutEffect`](/reference/react/useLayoutEffect) is a closer match. +对于大多数的使用场景来说,在类组件中一起定义 `componentDidMount`, `componentDidUpdate`, 和 `componentWillUnmount` 等同于在函数式组件中调用 [`useEffect`](/reference/react/useEffect) 。在一些少数的情况,例如在浏览器绘制前执行代码很重要时, [`useLayoutEffect`](/reference/react/useLayoutEffect) 是一个更合适的匹配。 -[See how to migrate.](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) @@ -308,9 +308,9 @@ For many use cases, defining `componentDidMount`, `componentDidUpdate`, and `com ### `componentDidUpdate(prevProps, prevState, snapshot?)` {/*componentdidupdate*/} -If you define the `componentDidUpdate` method, React will call it immediately after your component has been re-rendered with updated props or state. This method is not called for the initial render. +如果你定义了 `componentDidUpdate` 方法,当你的组件更新了 props 或 state 重新渲染后,React 将立即调用它。这个方法不会在首次渲染时调用。 -You can use it to manipulate the DOM after an update. This is also a common 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). Typically, you'd use it together with [`componentDidMount`](#componentdidmount) and [`componentWillUnmount`:](#componentwillunmount) +你可以在更新后使用它来操作 DOM 。这也是进行网络请求的常见位置,只要你将当前的 props 与以前的 props 进行比较即可(例如,如果 props 没有更改,则可能不需要网络请求)。一般来说, 这个方法与[`componentDidMount`](#componentdidmount) 以及 [`componentWillUnmount`:](#componentwillunmount) 一起使用。 ```js {10-18} class ChatRoom extends Component { @@ -340,34 +340,34 @@ class ChatRoom extends Component { } ``` -[See more examples.](#adding-lifecycle-methods-to-a-class-component) +[查看更多实例](#adding-lifecycle-methods-to-a-class-component) -#### Parameters {/*componentdidupdate-parameters*/} +#### 参数 {/*componentdidupdate-parameters*/} -* `prevProps`: Props before the update. Compare `prevProps` to [`this.props`](#props) to determine what changed. +* `prevProps`: 更新之前的 Props 。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: State before the update. Compare `prevState` to [`this.state`](#state) to determine what changed. +* `prevState`: 更新之前的 State 。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 -* `snapshot`: If you implemented [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate), `snapshot` will contain the value you returned from that method. Otherwise, it will be `undefined`. +* `snapshot`: 如果你设置了 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) ,那么 `snapshot` 将包含从该方法返回的值。否则,它将是 `undefined` 。 -#### Returns {/*componentdidupdate-returns*/} +#### 返回值 {/*componentdidupdate-returns*/} -`componentDidUpdate` should not return anything. +`componentDidUpdate` 不应该返回任何值。 -#### Caveats {/*componentdidupdate-caveats*/} +#### 说明 {/*componentdidupdate-caveats*/} -- `componentDidUpdate` will not get called if [`shouldComponentUpdate`](#shouldcomponentupdate) is defined and returns `false`. +- 如果你定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并且返回 false 的话,那么 `componentDidUpdate` 将不会被调用。 -- The logic inside `componentDidUpdate` should usually be wrapped in conditions comparing `this.props` with `prevProps`, and `this.state` with `prevState`. Otherwise, there's a risk of creating infinite loops. +- `componentDidUpdate` 内部的逻辑通常应该包含在比较 `this.props` 与 `prevProps` 和 `this.state` 与 `prevState` 之中。 否则,就会存在创建无限循环的风险。 -- Although you may call [`setState`](#setstate) immediately in `componentDidUpdate`, it's best to avoid that when you can. It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the [`render`](#render) will be called twice in this case, the user won't see the intermediate state. This pattern often causes performance issues, but it may be necessary for rare cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position. +- 虽然可以在 `componentDidUpdate` 中立即调用 [`setState`](#setstate) ,但最好尽可能避免这样做。它将触发一个额外的渲染,但它将在浏览器更新屏幕之前发生。 这导致了即使 [`render`](#render) 在这种情况下会被调用两次, 用户也不会看到中间状态。这种模式通常会导致性能问题,但在模态和工具提示等少数情况下,当你需要在呈现依赖于其大小或位置的内容之前测量DOM节点时,可能需要使用这种模式。 -For many use cases, defining `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` together in class components is equivalent to calling [`useEffect`](/reference/react/useEffect) in function components. In the rare cases where it's important for the code to run before browser paint, [`useLayoutEffect`](/reference/react/useLayoutEffect) is a closer match. +对于大多数用例来说, 在类组件中一起定义 `componentDidMount` , `componentDidUpdate` , 和 `componentWillUnmount` 相当于在函数式组件中定义了 [`useEffect`](/reference/react/useEffect) 。在少数情况下,代码在浏览器绘制之前运行很重要,这时 [`useLayoutEffect`](/reference/react/useLayoutEffect) 是更佳的匹配。 -[See how to migrate.](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) --- @@ -376,9 +376,9 @@ For many use cases, defining `componentDidMount`, `componentDidUpdate`, and `com -This API has been renamed from `componentWillMount` to [`UNSAFE_componentWillMount`.](#unsafe_componentwillmount) The old name has been deprecated. In a future major version of React, only the new name will work. +此 API 已从 `componentWillMount` 重命名为 [`UNSAFE_componentWillMount`.](#unsafe_componentwillmount) ,旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 -Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components. +运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -388,9 +388,9 @@ Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-co -This API has been renamed from `componentWillReceiveProps` to [`UNSAFE_componentWillReceiveProps`.](#unsafe_componentwillreceiveprops) The old name has been deprecated. In a future major version of React, only the new name will work. +此 API 已从 `componentWillReceiveProps` 重命名为 [`UNSAFE_componentWillReceiveProps`.](#unsafe_componentwillreceiveprops) ,旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 -Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components. +运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -400,9 +400,9 @@ Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-co -This API has been renamed from `componentWillUpdate` to [`UNSAFE_componentWillUpdate`.](#unsafe_componentwillupdate) The old name has been deprecated. In a future major version of React, only the new name will work. +此 API 已从 `componentWillUpdate` 重命名为 [`UNSAFE_componentWillUpdate`.](#unsafe_componentwillupdate) ,旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 -Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) to automatically update your components. +运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -410,9 +410,9 @@ Run the [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-co ### `componentWillUnmount()` {/*componentwillunmount*/} -If you define the `componentWillUnmount` method, React will call it before your component is removed *(unmounted)* from the screen. This is a common place to cancel data fetching or remove subscriptions. +如果你定义了 `componentWillUnmount` 方法,React 会在你的组件被移除屏幕之前 *(unmounted)* 调用它。这是取消数据获取或删除监听的常见位置。 -The logic inside `componentWillUnmount` should "mirror" the logic inside [`componentDidMount`.](#componentdidmount) For example, if `componentDidMount` sets up a subscription, `componentWillUnmount` should clean up that subscription. If the cleanup logic in your `componentWillUnmount` reads some props or state, you will usually also need to implement [`componentDidUpdate`](#componentdidupdate) to clean up resources (such as subscriptions) corresponding to the old props and state. +`componentWillUnmount` 内部的逻辑应该覆盖全 [`componentDidMount`.](#componentdidmount) 内部的逻辑, 例如,如果在 `componentDidMount` 中设置了一个监听,那么 `componentWillUnmount` 中应该清除掉这个监听。如果你 `componentWillUnmount` 的清理逻辑中读取了一些 props 或者 state ,那么你通常还需要实现一个 [`componentDidUpdate`](#componentdidupdate) 来清理旧 props 和 state 对应的资源(例如监听)。 ```js {20-22} class ChatRoom extends Component { @@ -442,25 +442,25 @@ class ChatRoom extends Component { } ``` -[See more examples.](#adding-lifecycle-methods-to-a-class-component) +[查看更多示例](#adding-lifecycle-methods-to-a-class-component) -#### Parameters {/*componentwillunmount-parameters*/} +#### 参数 {/*componentwillunmount-parameters*/} -`componentWillUnmount` does not take any parameters. +`componentWillUnmount` 不需要任何参数。 -#### Returns {/*componentwillunmount-returns*/} +#### 返回值 {/*componentwillunmount-returns*/} -`componentWillUnmount` should not return anything. +`componentWillUnmount` 不应该返回任何值。 -#### Caveats {/*componentwillunmount-caveats*/} +#### 说明 {/*componentwillunmount-caveats*/} -- When [Strict Mode](/reference/react/StrictMode) is on, in development React will call [`componentDidMount`,](#componentdidmount) then immediately call `componentWillUnmount`, and then call `componentDidMount` again. This helps you notice if you forgot to implement `componentWillUnmount` or if its logic doesn't fully "mirror" what `componentDidMount` does. +- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发中React会调用[`componentDidMount`,](#componentdidmount),然后立即调用 `componentWillUnmount` ,然后再次调用 `componentDidMount` 。这可以帮助你注意到你是否忘记实现 `componentWillUnmount` ,或者它的逻辑是否没有完全覆盖到 `componentDidMount` 的作用。 -For many use cases, defining `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` together in class components is equivalent to calling [`useEffect`](/reference/react/useEffect) in function components. In the rare cases where it's important for the code to run before browser paint, [`useLayoutEffect`](/reference/react/useLayoutEffect) is a closer match. +对于许多用例,在类组件中一起定义 `componentDidMount` 、 `componentDidUpdate` 和 `componentWillUnmount` 相当于在函数式组件中调用 [`useEffect`](/reference/react/useEffect) 。在少数情况下,代码在浏览器绘制之前运行很重要时,[`useLayoutEffect`](/reference/react/useLayoutEffect) 是更为接近的匹配。 -[See how to migrate.](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) @@ -468,27 +468,27 @@ For many use cases, defining `componentDidMount`, `componentDidUpdate`, and `com ### `forceUpdate(callback?)` {/*forceupdate*/} -Forces a component to re-render. +强制组件重新渲染。 -Usually, this is not necessary. If your component's [`render`](#render) method only reads from [`this.props`](#props), [`this.state`](#state), or [`this.context`,](#context) it will re-render automatically when you call [`setState`](#setstate) inside your component or one of its parents. However, if your component's `render` method reads directly from an external data source, you have to tell React to update the user interface when that data source changes. That's what `forceUpdate` lets you do. +通常来说,这是没有必要的。如果组件的 [`render`](#render) 方法仅读取了 [`this.props`](#props) 、 [`this.state`](#state) 或 [`this.context`,]( #context) 时,当你在组件或其父组件之一内调用 [`setState`](#setstate) 时,它就将自动重新渲染。但是,如果组件的 `render` 方法直接从外部数据源读取,则必须告诉 React 在该数据源更改时更新用户界面。这就是你可以用 `forceUpdate` 做的事。 -Try to avoid all uses of `forceUpdate` and only read from `this.props` and `this.state` in `render`. +尽量避免使用 `forceUpdate` 并且在 `render` 中只读取 `this.props` 和 `this.state` 。 -#### Parameters {/*forceupdate-parameters*/} +#### 参数 {/*forceupdate-parameters*/} -* **optional** `callback` If specified, React will call the `callback` you've provided after the update is committed. +* **optional** `callback` 如果有指定,React 将在提交更新后调用你提供的 `callback` 。 -#### Returns {/*forceupdate-returns*/} +#### 返回值 {/*forceupdate-returns*/} -`forceUpdate` does not return anything. +`forceUpdate` 不返回任何值。 -#### Caveats {/*forceupdate-caveats*/} +#### 说明 {/*forceupdate-caveats*/} -- If you call `forceUpdate`, React will re-render without calling [`shouldComponentUpdate`.](#shouldcomponentupdate) +- 如果你调用了 `forceUpdate`, React 将重新渲染而且不会调用 [`shouldComponentUpdate`。](#shouldComponentupdate) -Reading an external data source and forcing class components to re-render in response to its changes with `forceUpdate` has been superseded by [`useSyncExternalStore`](/reference/react/useSyncExternalStore) in function components. +读取外部数据源并强制类组件使用 `forceUpdate` 来重新渲染更改已被函数式组件中的 [`useSyncExternalStore`](/reference/react/useSyncExternalStore) 所取代。 @@ -498,19 +498,19 @@ Reading an external data source and forcing class components to re-render in res -This API will be removed in a future major version of React. [Use `Context.Provider` instead.](/reference/react/createContext#provider) +该 API 将在 React 的未来主要版本中删除。 [使用 `Context.Provider` 代替。](/reference/react/createContext#provider) -Lets you specify the values for the [legacy context](https://reactjs.org/docs/legacy-context.html) is provided by this component. +允许你指定由该组件提供的 [legacy context](https://reactjs.org/docs/legacy-context.html) 的值。 --- ### `getSnapshotBeforeUpdate(prevProps, prevState)` {/*getsnapshotbeforeupdate*/} -If you implement `getSnapshotBeforeUpdate`, React will call it immediately before React updates 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 method will be passed as a parameter to [`componentDidUpdate`.](#componentdidupdate) +如果你实现 `getSnapshotBeforeUpdate` ,React 会在 React 更新 DOM 之前立即调用它。它使你的组件能够在 DOM 发生更改之前捕获一些信息(例如滚动位置)。此生命周期方法返回的任何值都将作为参数传递给 [`componentDidUpdate`。](#componentdidupdate) -For example, you can use it in a UI like a chat thread that needs to preserve its scroll position during updates: +例如,你可以在 UI 中像是需要在更新期间保留其滚动位置的聊天消息来使用它。 ```js {7-15,17} class ScrollingList extends React.Component { @@ -520,8 +520,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. + // 我们是否要向列表中添加新项目? + // 捕获滚动​​位置,以便我们稍后可以调整滚动。 if (prevProps.list.length < this.props.list.length) { const list = this.listRef.current; return list.scrollHeight - list.scrollTop; @@ -530,9 +530,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是getSnapshotBeforeUpdate返回的值) if (snapshot !== null) { const list = this.listRef.current; list.scrollTop = list.scrollHeight - snapshot; @@ -547,25 +547,25 @@ class ScrollingList extends React.Component { } ``` -In the above example, it is important to read the `scrollHeight` property directly in `getSnapshotBeforeUpdate`. It is not safe to read it in [`render`](#render), [`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops), or [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate) because there is a potential time gap between these methods getting called and React updating the DOM. +在上面的示例中,直接在 `getSnapshotBeforeUpdate` 中读取 `scrollHeight` 属性非常重要。在 [`render`](#render) 、 [`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops) 或 [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate) 中读取它是不安全的,因为在这些方法被调用和 React 更新 DOM 之间存在潜在的时间间隔。 -#### Parameters {/*getsnapshotbeforeupdate-parameters*/} +#### 参数 {/*getsnapshotbeforeupdate-parameters*/} -* `prevProps`: Props before the update. Compare `prevProps` to [`this.props`](#props) to determine what changed. +* `prevProps`: 更新之前的 Props 。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: State before the update. Compare `prevState` to [`this.state`](#state) to determine what changed. +* `prevState`: 更新之前的 State 。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 -#### Returns {/*getsnapshotbeforeupdate-returns*/} +#### 返回值 {/*getsnapshotbeforeupdate-returns*/} -You should return a snapshot value of any type that you'd like, or `null`. The value you returned will be passed as the third argument to [`componentDidUpdate`.](#componentdidupdate) +你应该返回你想要的任何类型的快照值,或者 `null` 。你返回的值将作为第三个参数传递给 [`componentDidUpdate`。](#componentdidupdate) 。 -#### Caveats {/*getsnapshotbeforeupdate-caveats*/} +#### 说明 {/*getsnapshotbeforeupdate-caveats*/} -- `getSnapshotBeforeUpdate` will not get called if [`shouldComponentUpdate`](#shouldcomponentupdate) is defined and returns `false`. +- 如果定义了 [`shouldComponentUpdate`](#shouldcomponentUpdate) 并返回了 `false` ,则不会调用 `getSnapshotBeforeUpdate` 。 -At the moment, there is no equivalent to `getSnapshotBeforeUpdate` for function components. This use case is very uncommon, but if you have the need for it, for now you'll have to write a class component. +目前,函数式组件中还没有与 `getSnapshotBeforeUpdate` 等效的API。这种用例非常罕见,但如果你有需要,那么你必须编写一个类组件。 @@ -573,9 +573,9 @@ At the moment, there is no equivalent to `getSnapshotBeforeUpdate` for function ### `render()` {/*render*/} -The `render` method is the only required method in a class component. +`render` 方法是类组件中唯一必需的方法。 -The `render` method should specify what you want to appear on the screen, for example: +`render` 方法应该指定你想要在屏幕上显示的内容,例如: ```js {4-6} import { Component } from 'react'; @@ -587,35 +587,35 @@ class Greeting extends Component { } ``` -React may call `render` at any moment, so you shouldn't assume that it runs at a particular time. Usually, the `render` method should return a piece of [JSX](/learn/writing-markup-with-jsx), but a few [other return types](#render-returns) (like strings) are supported. To calculate the returned JSX, the `render` method can read [`this.props`](#props), [`this.state`](#state), and [`this.context`](#context). +React 可能随时调用 `render` ,因此你不应该假设它在特定时间运行。通常, `render` 方法应该返回一段 [JSX](/learn/writing-markup-with-jsx),但也支持一些 [其他返回类型](#render-returns)(如字符串)。为了计算返回的 JSX ,`render` 方法可以读取 [`this.props`](#props)、[`this.state`](#state) 和 [`this.context`](#context) 。 -You should write the `render` method as a pure function, meaning that it should return the same result if props, state, and context are the same. It also shouldn't contain side effects (like setting up subscriptions) or interact with the browser APIs. Side effects should happen either in event handlers or methods like [`componentDidMount`.](#componentdidmount) +你应该将 `render` 方法编写为纯函数,这意味着如果 props、state 和 context 相同,它应该返回相同的结果。它也不应该包含额外的作用(例如设置监听)或与浏览器 API 交互。额外的作用应该发生在事件处理程序或 [`componentDidMount`.](#componentdidmount) 等方法中。 -#### Parameters {/*render-parameters*/} +#### 参数 {/*render-parameters*/} -* `prevProps`: Props before the update. Compare `prevProps` to [`this.props`](#props) to determine what changed. +* `prevProps`: 更新之前的 Props 。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: State before the update. Compare `prevState` to [`this.state`](#state) to determine what changed. +* `prevState`: 更新之前的 State 。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 -#### Returns {/*render-returns*/} +#### 返回值 {/*render-returns*/} -`render` can return any valid React node. This includes React elements such as `
`, strings, numbers, [portals](/reference/react-dom/createPortal), empty nodes (`null`, `undefined`, `true`, and `false`), and arrays of React nodes. +`render` 可以返回任何有效的 React 节点。这包括 React 元素,例如 `
`、字符串、数字、 [portals](/reference/react-dom/createPortal) 、空节点(`null`、`undefined`、`true` 和 `false` )和 React 节点数组。 -#### Caveats {/*render-caveats*/} +#### 说明 {/*render-caveats*/} -- `render` should be written as a pure function of props, state, and context. It should not have side effects. +- `render` 应该写成 props 、 state 和 context 的纯函数,它不应该包含额外的作用。 -- `render` will not get called if [`shouldComponentUpdate`](#shouldcomponentupdate) is defined and returns `false`. +- 如果定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并返回 `false`,则不会调用 `render`。 -- When [Strict Mode](/reference/react/StrictMode) is on, React will call `render` twice in development and then throw away one of the results. This helps you notice the accidental side effects that need to be moved out of the `render` method. +- 当 [严格模式](/reference/react/StrictMode) 开启时,React 将在开发过程中调用 `render` 两次,然后丢弃其中一个结果。这可以帮助你注意到需要从 `render` 方法中移出的意外副作用。 -- There is no one-to-one correspondence between the `render` call and the subsequent `componentDidMount` or `componentDidUpdate` call. Some of the `render` call results may be discarded by React when it's beneficial. +- `render` 调用和后续的 `componentDidMount` 或 `componentDidUpdate` 调用之间没有一一对应的关系。当这样更好时,React 可能会丢弃一些 `render` 的调用结果。 --- ### `setState(nextState, callback?)` {/*setstate*/} -Call `setState` to update the state of your React component. +调用 `setState` 来更新 React 组件的 state 。 ```js {8-10} class Form extends Component { @@ -641,11 +641,11 @@ class Form extends Component { } ``` -`setState` enqueues changes to the component state. It tells React that this component and its children need to re-render with the new state. This is the main way you'll update the user interface in response to interactions. +`setState` 将组件的 state 的更改加入队列。它告诉 React 该组件及其子组件需要使用新状态重新渲染。这是更新用户界面以响应交互的主要方式。 -Calling `setState` **does not** change the current state in the already executing code: +调用 `setState` 时 **不会** 更改已执行代码中的当前状态: ```js {6} function handleClick() { @@ -653,15 +653,15 @@ function handleClick() { this.setState({ name: 'Robin' }); - console.log(this.state.name); // Still "Taylor"! + console.log(this.state.name); // 依然是 "Taylor"! } ``` -It only affects what `this.state` will return starting from the *next* render. +它只影响从 **下一个** 渲染开始返回的 `this.state` 。 -You can also pass a function to `setState`. It lets you update state based on the previous state: +你还可以将函数传递给 `setState` 。它允许你根据先前的 state 来更新 state: ```js {2-6} handleIncreaseAge = () => { @@ -673,31 +673,31 @@ You can also pass a function to `setState`. It lets you update state based on th } ``` -You don't have to do this, but it's handy if you want to update state multiple times during the same event. +你不必这样做,但如果你想在同一事件期间多次更新状态,这会很方便。 -#### Parameters {/*setstate-parameters*/} +#### 参数 {/*setstate-parameters*/} -* `nextState`: Either an object or a function. - * If you pass an object as `nextState`, it will be shallowly merged into `this.state`. - * If you pass a function as `nextState`, it will be treated as an _updater function_. It must be pure, should take the pending state and props as arguments, and should return the object to be shallowly merged into `this.state`. React will put your updater function in a queue and re-render your component. During the next render, React will calculate the next state by applying all of the queued updaters to the previous state. +* `nextState`: 一个对象或者函数。 + * 如果你传递一个对象作为 `nextState` ,它将浅层合并到 `this.state` 中。 + * 如果你传递一个函数作为 `nextState` ,它将被视为 **更新函数** 。它必须是个纯函数,应该以已加载的 state 和 props 作为参数,并且应该返回要浅层合并到 `this.state` 中的对象。 React 会将你的更新函数放入队列中并重新渲染你的组件。在下一次渲染期间,React 将通过应用队列中的所有更新程序来计算下一个 state 。 -* **optional** `callback`: If specified, React will call the `callback` you've provided after the update is committed. +* **可选的** `callback`: 如果指定,React 将在提交更新后调用你提供的 `回调` 。 -#### Returns {/*setstate-returns*/} +#### 返回值 {/*setstate-returns*/} -`setState` does not return anything. +`setState` 不会返回任何值。 -#### Caveats {/*setstate-caveats*/} +#### 说明 {/*setstate-caveats*/} -- Think of `setState` as a *request* rather than an immediate command to update the component. When multiple components update their state in response to an event, React will batch their updates and re-render them together in a single pass at the end of the event. In the rare case that you need to force a particular state update to be applied synchronously, you may wrap it in [`flushSync`,](/reference/react-dom/flushSync) but this may hurt performance. +- 将 `setState` 视为 **请求** ,而不是立即会更新组件的命令。当多个组件更新它们的 state 以响应事件时, React 将批量更新它们,并在这次事件结束时将它们一起重新渲染。在极少数情况下,你需要强制同步应用特定的状态更新,你可以将其包装在 [`flushSync`,](/reference/react-dom/flushSync) 中,但这可能会损害性能。 -- `setState` does not update `this.state` immediately. This makes reading `this.state` right after calling `setState` a potential pitfall. Instead, use [`componentDidUpdate`](#componentdidupdate) or the setState `callback` argument, 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, you can pass a function to `nextState` as described above. +- `setState` 不会立即更新 `this.state`。这让在调用 `setState` 之后立即读取 `setState` 成为一个潜在的陷阱。相反,请使用 [`componentDidUpdate`](#componentdidupdate) 或 setState `callback` 参数,其中任何一个都保证在更新后触发。如果需要根据前一个状态来设置状态,可以将函数传递给 `nextState` ,如上所述。 -Calling `setState` in class components is similar to calling a [`set` function](/reference/react/useState#setstate) in function components. +在类组件中调用 `setState` 等同于在函数式组件中调用 [`set` 函数](/reference/react/useState#setstate) 。 -[See how to migrate.](#migrating-a-component-with-state-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function) @@ -705,9 +705,9 @@ Calling `setState` in class components is similar to calling a [`set` function]( ### `shouldComponentUpdate(nextProps, nextState, nextContext)` {/*shouldcomponentupdate*/} -If you define `shouldComponentUpdate`, React will call it to determine whether a re-render can be skipped. +如果你定义了 `shouldComponentUpdate` ,React 将调用它来确定是否可以跳过重新渲染。 -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. +如果你确信你想手动编写它,你可以将`this.props`与`nextProps`进行比较,将`this.state`与`nextState`进行比较,并返回`false`来告诉React可以跳过更新。 ```js {6-18} class Rectangle extends Component { @@ -723,7 +723,7 @@ class Rectangle extends Component { nextProps.size.height === this.props.size.height && nextState.isHovered === this.state.isHovered ) { - // Nothing has changed, so a re-render is unnecessary + // 没有任何改变,因此不需要重新渲染 return false; } return true; @@ -734,35 +734,35 @@ class Rectangle extends Component { ``` -React calls `shouldComponentUpdate` 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`](#forceupdate) is used. +当收到新的 props 或 state 时,React 会在渲染之前调用 `shouldComponentUpdate` ,默认为 `true` 。初始渲染或使用 [`forceUpdate`](#forceupdate) 时将不会调用此方法。 -#### Parameters {/*shouldcomponentupdate-parameters*/} +#### 参数 {/*shouldcomponentupdate-parameters*/} -- `nextProps`: The next props that the component is about to render with. Compare `nextProps` to [`this.props`](#props) to determine what changed. -- `nextState`: The next state that the component is about to render with. Compare `nextState` to [`this.state`](#props) to determine what changed. -- `nextContext`: The next context that the component is about to render with. Compare `nextContext` to [`this.context`](#context) to determine what changed. Only available if you specify [`static contextType`](#static-contexttype) (modern) or [`static contextTypes`](#static-contexttypes) (legacy). +- `nextProps`: 组件即将用来渲染的下一个 props 。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 +- `nextState`: 组件即将渲染的下一个 state 。将 `nextState` 与 [`this.state`](#props) 进行比较以确定发生了什么变化。 +- `nextContext`: 组件将要渲染的下一个上下文。将 `nextContext` 与 [`this.context`](#context) 进行比较以确定发生了什么变化。仅当你指定了 [`static contextType`](#static-contexttype)(更新的)或 [`static contextTypes`](#static-contexttypes)(旧版)时才可用。 -#### Returns {/*shouldcomponentupdate-returns*/} +#### 返回值 {/*shouldcomponentupdate-returns*/} -Return `true` if you want the component to re-render. That's the default behavior. +返回 `true` 如果你希望组件重新渲染。这是默认返回。 -Return `false` to tell React that re-rendering can be skipped. +返回 `false` 来告诉 React 可以跳过重新渲染。 -#### Caveats {/*shouldcomponentupdate-caveats*/} +#### 说明 {/*shouldcomponentupdate-caveats*/} -- This method *only* exists as a performance optimization. If your component breaks without it, fix that first. +- 此方法 **仅仅** 作为性能优化而存在。如果你的组件在没有它的情况下损坏,请先修复组件。 -- Consider using [`PureComponent`](/reference/react/PureComponent) instead of writing `shouldComponentUpdate` by hand. `PureComponent` shallowly compares props and state, and reduces the chance that you'll skip a necessary update. +- 可以考虑使用 [`PureComponent`](/reference/react/PureComponent) 而不是手动编写 `shouldComponentUpdate` 。 `PureComponent` 浅层比较 props 和 state ,并减少你跳过必要更新的机会。 -- We do not recommend doing deep equality checks or using `JSON.stringify` in `shouldComponentUpdate`. It makes performance unpredictable and dependent on the data structure of every prop and state. In the best case, you risk introducing multi-second stalls to your application, and in the worst case you risk crashing it. +- 我们不建议在 `shouldComponentUpdate` 中进行深度相等检查或使用 `JSON.stringify` 。它使性能变得不可预测,并且依赖于每个 prop 和 state 的数据结构。在最好的情况下,你可能会冒着给应用程序引入多秒停顿的风险,而在最坏的情况下,你可能会面临使应用程序崩溃的风险。 -- Returning `false` does not prevent child components from re-rendering when *their* state changes. +- 返回 `false` 并不会阻止子组件在 **他们的** state 发生变化时重新渲染。 -- Returning `false` does not *guarantee* that the component will not re-render. React will use the return value as a hint but it may still choose to re-render your component if it makes sense to do for other reasons. +- 返回 `false` 并不能 **确保** 组件不会重新渲染。 React 将使用返回值作为提示,但如果出于其他有意义原因,它仍然可能选择重新渲染你的组件。 -Optimizing class components with `shouldComponentUpdate` is similar to optimizing function components with [`memo`.](/reference/react/memo) Function components also offer more granular optimization with [`useMemo`.](/reference/react/useMemo) +使用 `shouldComponentUpdate` 优化类组件与使用 [`memo`.](/reference/react/memo) 优化函数式组件类似。函数式组件还使用 [`useMemo`.](/reference/react/useMemo) 来提供更精细的优化。 @@ -770,32 +770,34 @@ Optimizing class components with `shouldComponentUpdate` is similar to optimizin ### `UNSAFE_componentWillMount()` {/*unsafe_componentwillmount*/} -If you define `UNSAFE_componentWillMount`, React will call it immediately after the [`constructor`.](#constructor) It only exists for historical reasons and should not be used in any new code. Instead, use one of the alternatives: +如果你定义了 `UNSAFE_componentWillMount` ,React 会在 [`constructor`](#constructor) 之后立即调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反,请使用一种替代方案: + +- 要初始化状态,请将 [`state`](#state) 声明为类字段或在 [`constructor`.](#constructor) 内设置 `this.state` 。 -- To initialize state, declare [`state`](#state) as a class field or set `this.state` inside the [`constructor`.](#constructor) -- If you need to run a side effect or set up a subscription, move that logic to [`componentDidMount`](#componentdidmount) instead. +- 如果你需要运行额外作用或设置监听,请将该逻辑移至 [`componentDidMount`](#componentdidmount) 。 -[See examples of migrating away from unsafe lifecycles.](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples) +[查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples) -#### Parameters {/*unsafe_componentwillmount-parameters*/} +#### 参数 {/*unsafe_componentwillmount-parameters*/} -`UNSAFE_componentWillMount` does not take any parameters. +`UNSAFE_componentWillMount` 不需要任何参数。 -#### Returns {/*unsafe_componentwillmount-returns*/} +#### 返回值 {/*unsafe_componentwillmount-returns*/} -`UNSAFE_componentWillMount` should not return anything. +`UNSAFE_componentWillMount` 不应该返回任何值。 -#### Caveats {/*unsafe_componentwillmount-caveats*/} +#### 说明 {/*unsafe_componentwillmount-caveats*/} -- `UNSAFE_componentWillMount` will not get called if the component implements [`static getDerivedStateFromProps`](#static-getderivedstatefromprops) or [`getSnapshotBeforeUpdate`.](#getsnapshotbeforeupdate) +- 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`.](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillMount` . -- Despite its naming, `UNSAFE_componentWillMount` does not guarantee that the component *will* get mounted if your app uses modern React features like [`Suspense`.](/reference/react/Suspense) If a render attempt is suspended (for example, because the code for some child component has not loaded yet), React will throw the in-progress tree away and attempt to construct the component from scratch during the next attempt. This is why this method is "unsafe". Code that relies on mounting (like adding a subscription) should go into [`componentDidMount`.](#componentdidmount) +- 即使它的名字是这样的,但是如果你的应用程序使用 [`Suspense`.](/reference/react/Sus​​pense) 等现代 React 功能时,`UNSAFE_componentWillMount` 不保证组件 **将** 被安装。(例如,因为某些子组件的代码尚未加载。) React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。 这就是为什么这种方法是 **不安全** 的。依赖于挂载(例如添加监听)的代码应放入 [`componentDidMount`。](#componentdidmount) -- `UNSAFE_componentWillMount` is the only lifecycle method that runs during [server rendering.](/reference/react-dom/server) For all practical purposes, it is identical to [`constructor`,](#constructor) so you should use the `constructor` for this type of logic instead. +- `UNSAFE_componentWillMount` 是用于所有实际目的在[服务器渲染](/reference/react-dom/server)期间运行的唯一生命周期方法,它与 [`constructor`,](#constructor) 相同,因此你应该使用 `constructor` 来代替这种类型的逻辑。 -Calling [`setState`](#setstate) inside `UNSAFE_componentWillMount` in a class component to initialize state is equivalent to passing that state as the initial state to [`useState`](/reference/react/useState) in a function component. +在类组件中的 `UNSAFE_componentWillMount` 内部调用 [`setState`](#setstate) 来初始化状态等同于函数式组件中用该 state 作为初始状态传递给 [`useState`] 。 + @@ -803,37 +805,37 @@ Calling [`setState`](#setstate) inside `UNSAFE_componentWillMount` in a class co ### `UNSAFE_componentWillReceiveProps(nextProps, nextContext)` {/*unsafe_componentwillreceiveprops*/} -If you define `UNSAFE_componentWillReceiveProps`, React will call it when the component receives new props. It only exists for historical reasons and should not be used in any new code. Instead, use one of the alternatives: +如果你定义了 `UNSAFE_componentWillReceiveProps` ,React 会在组件收到新的 props 时调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反,请使用以下替代方案: -- If you need to **run a side effect** (for example, fetch data, run an animation, or reinitialize a subscription) in response to prop changes, move that logic to [`componentDidUpdate`](#componentdidupdate) instead. -- If you need to **avoid re-computing some data only when a prop changes,** use a [memoization helper](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization) instead. -- If you need to **"reset" some state when a prop changes,** consider either making a component [fully controlled](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) or [fully uncontrolled with a key](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) instead. -- If you need to **"adjust" some state when a prop changes,** check whether you can compute all the necessary information from props alone during rendering. If you can't, use [`static getDerivedStateFromProps`](/reference/react/Component#static-getderivedstatefromprops) instead. +- 如果你需要 **运行额外作用** (例如,获取数据、运行动画或重新初始化监听)来响应 prop 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate) +- 如果你需要 **避免仅在 prop 更改时重新计算某些数据** 请使用 [memoization helper](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization) 代替。 +- 如果你需要 **在 prop 更改时`重置`某些状态**考虑制作一个组件 [fully uncontrolled](https://legacy.reactjs.org/blog/2018/06/07/you-probously-不需要派生状态。html#recommendation-fully-controlled-component) 或者 [fully uncontrolled with a key](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) instead. +- 如果你需要 **在 prop 更改时`调整`某些状态,** 检查你是否可以在渲染期间单独从 props 计算所有必要的信息。如果不能,请改用 [`static getDerivedStateFromProps`](/reference/react/Component#static-getdrivenstatefromprops)。 -[See examples of migrating away from unsafe lifecycles.](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props) +[查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props) -#### Parameters {/*unsafe_componentwillreceiveprops-parameters*/} +#### 参数 {/*unsafe_componentwillreceiveprops-parameters*/} -- `nextProps`: The next props that the component is about to receive from its parent component. Compare `nextProps` to [`this.props`](#props) to determine what changed. -- `nextContext`: The next props that the component is about to receive from the closest provider. Compare `nextContext` to [`this.context`](#context) to determine what changed. Only available if you specify [`static contextType`](#static-contexttype) (modern) or [`static contextTypes`](#static-contexttypes) (legacy). +- `nextProps`: 组件将从其父组件接收的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 +- `nextContext`: 组件将从最近的提供者处接收的下一个 props。将 `nextContext` 与 [`this.context`](#context) 进行比较以确定发生了什么变化。仅当你指定 [`static contextType`](#static-contexttype)(更新的)或 [`static contextTypes`](#static-contexttypes)(旧版)时才可用。 -#### Returns {/*unsafe_componentwillreceiveprops-returns*/} +#### 返回值 {/*unsafe_componentwillreceiveprops-returns*/} -`UNSAFE_componentWillReceiveProps` should not return anything. +`UNSAFE_componentWillReceiveProps` 不应该返回任何值。 -#### Caveats {/*unsafe_componentwillreceiveprops-caveats*/} +#### 说明 {/*unsafe_componentwillreceiveprops-caveats*/} -- `UNSAFE_componentWillReceiveProps` will not get called if the component implements [`static getDerivedStateFromProps`](#static-getderivedstatefromprops) or [`getSnapshotBeforeUpdate`.](#getsnapshotbeforeupdate) +- 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`.](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillReceiveProps` -- Despite its naming, `UNSAFE_componentWillReceiveProps` does not guarantee that the component *will* receive those props if your app uses modern React features like [`Suspense`.](/reference/react/Suspense) If a render attempt is suspended (for example, because the code for some child component has not loaded yet), React will throw the in-progress tree away and attempt to construct the component from scratch during the next attempt. By the time of the next render attempt, the props might be different. This is why this method is "unsafe". Code that should run only for committed updates (like resetting a subscription) should go into [`componentDidUpdate`.](#componentdidupdate) +- 即使它的名字是这样的, 如果你的应用程序使用 [`Suspense`.](/reference/react/Sus​​pense) 等现代 React 功能,`UNSAFE_componentWillReceiveProps` 不保证组件 **将** 接收这些 Props (例如,因为某些子组件的代码尚未加载), React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。 到下一次渲染尝试时,Props 可能会有所不同。这就是为什么这种方法 **不安全** 。仅为提交更新(例如重置监听)的代码应放入 [`componentDidUpdate`.](#componentdidupdate) -- `UNSAFE_componentWillReceiveProps` does not mean that the component has received *different* props than the last time. You need to compare `nextProps` and `this.props` yourself to check if something changed. +- `UNSAFE_componentWillReceiveProps` 并不意味着组件收到了与上次 **不同的** props 。你需要自己比较 `nextProps` 和 `this.props` 以检查是否发生了变化。 -- React doesn't call `UNSAFE_componentWillReceiveProps` with initial props during mounting. It only calls this method if some of component's props are going to be updated. For example, calling [`setState`](#setstate) doesn't generally trigger `UNSAFE_componentWillReceiveProps` inside the same component. +- React 在挂载期间不会使用初始 props 调用 `UNSAFE_componentWillReceiveProps` 。仅当组件的某些属性要更新时,它才会调用此方法。例如,在同一组件内调用 [`setState`](#setstate) 通常不会触发 `UNSAFE_componentWillReceiveProps`。 -Calling [`setState`](#setstate) inside `UNSAFE_componentWillReceiveProps` in a class component to "adjust" state is equivalent to [calling the `set` function from `useState` during rendering](/reference/react/useState#storing-information-from-previous-renders) in a function component. +在类组件中的 `UNSAFE_componentWillReceiveProps` 里调用 [`setState`](#setstate) 来“调整” state 等同于在函数式组件中调用[calling the `set` function from `useState` during rendering](/reference/react/useState#storing-information-from-previous-renders)。 @@ -842,39 +844,39 @@ Calling [`setState`](#setstate) inside `UNSAFE_componentWillReceiveProps` in a c ### `UNSAFE_componentWillUpdate(nextProps, nextState)` {/*unsafe_componentwillupdate*/} -If you define `UNSAFE_componentWillUpdate`, React will call it before rendering with the new props or state. It only exists for historical reasons and should not be used in any new code. Instead, use one of the alternatives: +如果你定义了`UNSAFE_componentWillUpdate`,React 会在使用新的 props 或 state 渲染之前调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反,请使用下面的替代方案: -- If you need to run a side effect (for example, fetch data, run an animation, or reinitialize a subscription) in response to prop or state changes, move that logic to [`componentDidUpdate`](#componentdidupdate) instead. -- If you need to read some information from the DOM (for example, to save the current scroll position) so that you can use it in [`componentDidUpdate`](#componentdidupdate) later, read it inside [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) instead. +- 如果你需要运行额外作用(例如,获取数据、运行动画或重新初始化监听)来响应 prop 或 state 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate) 。 +- 如果需要从 DOM 中读取一些信息(例如,保存当前滚动位置)以便稍后在 [`componentDidUpdate`](#componentdidupdate) 中使用的话,那么请在 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 中读取。 -[See examples of migrating away from unsafe lifecycles.](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples) +[查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples) -#### Parameters {/*unsafe_componentwillupdate-parameters*/} +#### 参数 {/*unsafe_componentwillupdate-parameters*/} -- `nextProps`: The next props that the component is about to render with. Compare `nextProps` to [`this.props`](#props) to determine what changed. -- `nextState`: The next state that the component is about to render with. Compare `nextState` to [`this.state`](#state) to determine what changed. +- `nextProps`: 组件即将用来渲染的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 -#### Returns {/*unsafe_componentwillupdate-returns*/} +- `nextState`: 组件即将渲染的下一个 state 。将 `nextState` 与 [`this.state`](#state) 进行比较以确定发生了什么变化。 -`UNSAFE_componentWillUpdate` should not return anything. +#### 返回值 {/*unsafe_componentwillupdate-returns*/} -#### Caveats {/*unsafe_componentwillupdate-caveats*/} +`UNSAFE_componentWillUpdate` 不应该返回任何值。 -- `UNSAFE_componentWillUpdate` will not get called if [`shouldComponentUpdate`](#shouldcomponentupdate) is defined and returns `false`. +#### 说明 {/*unsafe_componentwillupdate-caveats*/} -- `UNSAFE_componentWillUpdate` will not get called if the component implements [`static getDerivedStateFromProps`](#static-getderivedstatefromprops) or [`getSnapshotBeforeUpdate`.](#getsnapshotbeforeupdate) +- 如果定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并返回 `false`,则 `UNSAFE_componentWillUpdate` 将不会被调用。 -- It's not supported to call [`setState`](#setstate) (or any method that leads to `setState` being called, like dispatching a Redux action) during `componentWillUpdate`. +- 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`.](#getsnapshotbeforeupdate),则不会调用`UNSAFE_componentWillUpdate` -- Despite its naming, `UNSAFE_componentWillUpdate` does not guarantee that the component *will* update if your app uses modern React features like [`Suspense`.](/reference/react/Suspense) If a render attempt is suspended (for example, because the code for some child component has not loaded yet), React will throw the in-progress tree away and attempt to construct the component from scratch during the next attempt. By the time of the next render attempt, the props and state might be different. This is why this method is "unsafe". Code that should run only for committed updates (like resetting a subscription) should go into [`componentDidUpdate`.](#componentdidupdate) +- 不支持在 `componentWillUpdate` 期间调用 [`setState`](#setstate)(或任何导致调用 `setState` 的方法,例如分派 Redux 操作)。 -- `UNSAFE_componentWillUpdate` does not mean that the component has received *different* props or state than the last time. You need to compare `nextProps` with `this.props` and `nextState` with `this.state` yourself to check if something changed. +- 尽管它的命名是这样, `UNSAFE_componentWillUpdate` 并不能保证如果你的应用程序使用现代 React 功能(如 [`Suspense`.](/reference/react/Sus​​pense) )时,组件 **将会** 更新(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,props 和 state 可能会有所不同。 这就是为什么这种方法“不安全”。仅针对提交更新(例如重置监听)运行的代码应放入 [`componentDidUpdate`。](#componentdidupdate) -- React doesn't call `UNSAFE_componentWillUpdate` with initial props and state during mounting. +- `UNSAFE_componentWillUpdate` 并不意味着组件收到了与上次不同的 props 或状态。你需要自己将 `nextProps` 与 `this.props` 以及 `nextState` 与 `this.state` 进行比较,以检查是否发生了变化。 +- React 在挂载期间不会使用初始 props 和 state 调用 `UNSAFE_componentWillUpdate` 。 -There is no direct equivalent to `UNSAFE_componentWillUpdate` in function components. +函数式组件中没有与 `UNSAFE_componentWillUpdate` 直接dewng'tong的东西。 @@ -884,11 +886,11 @@ There is no direct equivalent to `UNSAFE_componentWillUpdate` in function compon -This API will be removed in a future major version of React. [Use `static contextType` instead.](#static-contexttype) +该 API 将在 React 的未来主要版本中删除。 [使用 `static contextType` 代替。](#static-contexttype) -Lets you specify which [legacy context](https://reactjs.org/docs/legacy-context.html) is provided by this component. +允许你指定此组件提供哪个[旧版上下文](https://reactjs.org/docs/legacy-context.html)。 --- @@ -896,17 +898,17 @@ Lets you specify which [legacy context](https://reactjs.org/docs/legacy-context. -This API will be removed in a future major version of React. [Use `static contextType` instead.](#static-contexttype) +该 API 将在 React 的未来主要版本中删除。 [使用 `static contextType` 代替。](#static-contexttype) -Lets you specify which [legacy context](https://reactjs.org/docs/legacy-context.html) is consumed by this component. +允许你指定此组件使用哪个[旧版上下文](https://reactjs.org/docs/legacy-context.html)。 --- ### `static contextType` {/*static-contexttype*/} -If you want to read [`this.context`](#context-instance-field) from your class component, you must specify which context it needs to read. The context you specify as the `static contextType` must be a value previously created by [`createContext`.](/reference/react/createContext) +如果你想从类组件中读取 [`this.context`](#context-instance-field),则必须指定它需要读取哪个 context 。你指定为 `static contextType` 的上下文必须是之前由 [`createContext` 创建的值。](/reference/react/createContext) ```js {2} class Button extends Component { @@ -926,9 +928,9 @@ class Button extends Component { -Reading `this.context` in class components is equivalent to [`useContext`](/reference/react/useContext) in function components. +在类组件中读取 `this.context` 等同于在函数组件中读取 [`useContext`](/reference/react/useContext) 。 -[See how to migrate.](#migrating-a-component-with-context-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-context-from-a-class-to-a-function) @@ -936,9 +938,9 @@ Reading `this.context` in class components is equivalent to [`useContext`](/refe ### `static defaultProps` {/*static-defaultprops*/} -You can define `static defaultProps` to set the default props for the class. They will be used for `undefined` and missing props, but not for `null` props. +你可以定义 `static defaultProps` 来设置类的默认 props 。它们将在props为 `undefined` 和缺少时使用 ,但不能用于 props 为 `null` 时 。 -For example, here is how you define that the `color` prop should default to `'blue'`: +例如,以下是如何定义 `color` 属性默认为 `blue` : ```js {2-4} class Button extends Component { @@ -952,7 +954,7 @@ class Button extends Component { } ``` -If the `color` prop is not provided or is `undefined`, it will be set by default to `'blue'`: +如果未提供 `color` props 或者为 `undefined` ,它将默认设置为 `blue` : ```js <> @@ -972,7 +974,7 @@ If the `color` prop is not provided or is `undefined`, it will be set by default -Defining `defaultProps` in class components is similar to using [default values](/learn/passing-props-to-a-component#specifying-a-default-value-for-a-prop) in function components. +在类组件中定义 `defaultProps` 类似于在函数式组件中使用[默认值](/learn/passing-props-to-a-component#specifying-a-default-value-for-a-prop)。 @@ -980,7 +982,7 @@ Defining `defaultProps` in class components is similar to using [default values] ### `static propTypes` {/*static-proptypes*/} -You can define `static propTypes` together with the [`prop-types`](https://www.npmjs.com/package/prop-types) library to declare the types of the props accepted by your component. These types will be checked during rendering and in development only. +你可以定义 `static propTypes` 和 [`prop-types`](https://www.npmjs.com/package/prop-types) 库来声明组件接受的 props 类型。这些类型仅在渲染和开发过程中进行检查。 ```js import PropTypes from 'prop-types'; @@ -1000,7 +1002,7 @@ class Greeting extends React.Component { -We recommend using [TypeScript](https://www.typescriptlang.org/) instead of checking prop types at runtime. +我们建议使用 [TypeScript](https://www.typescriptlang.org/) 而不是在运行时检查 prop 类型。 @@ -1008,27 +1010,27 @@ We recommend using [TypeScript](https://www.typescriptlang.org/) instead of chec ### `static getDerivedStateFromError(error)` {/*static-getderivedstatefromerror*/} -If you define `static getDerivedStateFromError`, React will call it when a child component (including distant children) throws an error during rendering. This lets you display an error message instead of clearing the UI. +如果你定义了`static getDerivedStateFromError`,当子组件(包括远程子组件)在渲染过程中抛出错误时,React 将调用它。这使你可以显示错误消息而不是清除 UI。 -Typically, it is used together with [`componentDidCatch`](#componentDidCatch) which lets you send the error report to some analytics service. A component with these methods is called an *error boundary.* +通常,它与 [`componentDidCatch`](#componentDidCatch) 一起使用,它可以让你将错误报告发送到某些分析服务。具有这些方法的组件称为 **错误边界。** -[See an example.](#catching-rendering-errors-with-an-error-boundary) +[查看示例](#catching-rendering-errors-with-an-error-boundary) -#### Parameters {/*static-getderivedstatefromerror-parameters*/} +#### 参数 {/*static-getderivedstatefromerror-parameters*/} -* `error`: The error that was thrown. In practice, it will usually be an instance of [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) but this is not guaranteed because JavaScript allows to [`throw`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) any value, including strings or even `null`. +* `error`: 被抛出的错误。实际上,它通常是 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,但这并不能保证,因为 JavaScript 允许 [`throw`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 任何值,包括字符串甚至 `null`。 -#### Returns {/*static-getderivedstatefromerror-returns*/} +#### 返回值 {/*static-getderivedstatefromerror-returns*/} -`static getDerivedStateFromError` should return the state telling the component to display the error message. +`static getDerivedStateFromError` 应该返回告诉组件显示错误消息的状态。 -#### Caveats {/*static-getderivedstatefromerror-caveats*/} +#### 说明 {/*static-getderivedstatefromerror-caveats*/} -* `static getDerivedStateFromError` should be a pure function. If you want to perform a side effect (for example, to call an analytics service), you need to also implement [`componentDidCatch`.](#componentdidcatch) +* `static getDerivedStateFromError` 应该是一个纯函数。如果你想执行额外作用(例如,调用分析服务),你还需要实现 [`componentDidCatch`.](#componentdidcatch) -There is no direct equivalent for `static getDerivedStateFromError` in function components yet. If you'd like to avoid creating class components, write a single `ErrorBoundary` component like above and use it throughout your app. Alternatively, use the [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) package which does that. +函数式组件中目前还没有与 `static getDerivedStateFromError` 直接等效的东西。 如果你想避免创建类组件,请像上面那样编写一个`ErrorBoundary` 组件,并在整个应用程序中使用它。或者,使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包来执行此操作。 @@ -1036,9 +1038,9 @@ There is no direct equivalent for `static getDerivedStateFromError` in function ### `static getDerivedStateFromProps(props, state)` {/*static-getderivedstatefromprops*/} -If you define `static getDerivedStateFromProps`, React will call it right before calling [`render`,](#render) both on the initial mount and on subsequent updates. It should return an object to update the state, or `null` to update nothing. +如果你定义了 `static getDerivedStateFromProps` ,React 会在初始挂载和后续更新时调用 [`render`](#render) 之前调用它。它应该返回一个对象来更新状态,或者返回 `null` 不更新任何内容。 -This method exists for [rare use cases](https://legacy.reactjs.org/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, this `Form` component resets the `email` state when the `userID` prop changes: +此方法适用于[少数罕见用例](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state) ,其中 state 取决于 props 随着时间的推移的变化。例如,当 `userID` 属性更改时,此 `Form` 组件会重置 `email` 状态: ```js {7-18} class Form extends Component { @@ -1048,9 +1050,9 @@ class Form extends Component { }; static getDerivedStateFromProps(props, state) { - // Any time the current user changes, - // Reset any parts of state that are tied to that user. - // In this simple example, that's just the email. + // 每当当前用户发生变化时, + // 重置与该用户关联的任何 state 部分。 + // 在这个简单的示例中,只是以电子邮件为例。 if (props.userID !== state.prevUserID) { return { prevUserID: props.userID, @@ -1064,46 +1066,45 @@ class Form extends Component { } ``` -Note that this pattern requires you to keep a previous value of the prop (like `userID`) in state (like `prevUserID`). +请注意,此模式要求你将 prop 的先前值(如 `userID` )保留在状态(如 `prevUserID` )中。 -Deriving state leads to verbose code and makes your components difficult to think about. [Make sure you're familiar with simpler alternatives:](https://legacy.reactjs.org/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) method instead. -- If you want to **re-compute some data only when a prop changes,** [use a memoization helper instead.](https://legacy.reactjs.org/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](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) or [fully uncontrolled with a key](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) instead. +派生 state 会导致代码冗长,并使你的组件难以理解。 [确保你熟悉更简单的替代方案:](https://legacy.reactjs.org/blog/2018/06/07/you-probously-dont-need-driven-state.html) +- 如果你需要 **执行副作用** (例如,数据获取或动画)以响应 props 的更改,请改用 [`componentDidUpdate`](#componentdidupdate) 方法。 +- 如果你想 **仅在 prop 更改时重新计算一些数据,**[使用记忆助手代替。](https://legacy.reactjs.org/blog/2018/06/07/you-probously-不需要派生状态.html#what-about-memoization) +-如果你想要 **当 prop 改变时 "重置" 一些 state,** 考虑制作一个组件[完全控制](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) 或者 [带key的完全非受控组件](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key)。 -#### Parameters {/*static-getderivedstatefromprops-parameters*/} +#### 参数 {/*static-getderivedstatefromprops-parameters*/} -- `props`: The next props that the component is about to render with. -- `state`: The next state that the component is about to render with. +- `props`: 组件即将用来渲染的下一个 props 。 +- `state`: 组件即将渲染的下一个 state 。 -#### Returns {/*static-getderivedstatefromprops-returns*/} +#### 返回值 {/*static-getderivedstatefromprops-returns*/} -`static getDerivedStateFromProps` return an object to update the state, or `null` to update nothing. +`static getDerivedStateFromProps` 返回一个对象以更新状态,或返回 `null` 不更新任何内容。 -#### Caveats {/*static-getderivedstatefromprops-caveats*/} +#### 说明 {/*static-getderivedstatefromprops-caveats*/} -- This method is fired on *every* render, regardless of the cause. This is different from [`UNSAFE_componentWillReceiveProps`](#unsafe_cmoponentwillreceiveprops), which only fires when the parent causes a re-render and not as a result of a local `setState`. +- 无论原因如何,此方法都会在 **每个** 渲染时触发。这与 [`UNSAFE_componentWillReceiveProps`](#unsafe_cmoponentwillreceiveprops) 不同,后者仅在父级导致重新渲染时触发,而不是由于本地 `setState` 的结果。 -- This method doesn't have access to the component instance. If you'd like, you can reuse some code between `static getDerivedStateFromProps` and the other class methods by extracting pure functions of the component props and state outside the class definition. +- 此方法无权访问组件实例。如果你愿意,你可以通过在类定义之外提取组件 props 和 state 的纯函数,在 `static getDerivedStateFromProps` 和其他类方法之间重用一些代码。 -Implementing `static getDerivedStateFromProps` in a class component is equivalent to [calling the `set` function from `useState` during rendering](/reference/react/useState#storing-information-from-previous-renders) in a function component. +在类组件中实现 `static getDerivedStateFromProps` 等同于于在函数式组件中[在渲染期间从 useState 调用 set 函数](/reference/react/useState#storing-information-from-previous-renders)。 --- -## Usage {/*usage*/} +## 用法 {/*usage*/} -### Defining a class component {/*defining-a-class-component*/} +### 定义类组件 {/*defining-a-class-component*/} -To define a React component as a class, extend the built-in `Component` class and define a [`render` method:](#render) +要将 React 组件定义为类,请扩展内置的 `Component` 类并定义 [`render` 方法:](#render) ```js import { Component } from 'react'; @@ -1115,9 +1116,9 @@ class Greeting extends Component { } ``` -React will call your [`render`](#render) method whenever it needs to figure out what to display on the screen. Usually, you will return some [JSX](/learn/writing-markup-with-jsx) from it. Your `render` method should be a [pure function:](https://en.wikipedia.org/wiki/Pure_function) it should only calculate the JSX. +每当 React 需要确定屏幕上显示的内容时,它就会调用你的 [`render`](#render) 方法。一般来说,你将让它返回一些 [JSX](/learn/writing-markup-with-jsx) 你的 `render` 方法应该是一个[纯函数:](https://en.wikipedia.org/wiki/Pure_function),它应该只计算 JSX。 -Similarly to [function components,](/learn/your-first-component#defining-a-component) a class component can [receive information by props](/learn/your-first-component#defining-a-component) from its parent component. However, the syntax for reading props is different. For example, if the parent component renders ``, then you can read the `name` prop from [`this.props`](#props), like `this.props.name`: +与[函数式组件](/learn/your-first-component#defining-a-component)类似,类组件可以从它的父组件[通过props接收信息](/learn/your-first-component#defining-a-component) 。然而,读取 props 的语法是不同的。例如,如果父组件渲染 ``,那么你可以从 [`this.props`](#props) 读取 `name` 属性,例如 `this.props.name` : @@ -1143,19 +1144,19 @@ export default function App() { -Note that Hooks (functions starting with `use`, like [`useState`](/reference/react/useState)) are not supported inside class components. +请注意,类组件内部不支持 Hook(以 `use` 开头的函数,例如 [`useState`](/reference/react/useState) )。 -We recommend defining components as functions instead of classes. [See how to migrate.](#migrating-a-simple-component-from-a-class-to-a-function) +我们建议将组件定义为函数而不是类。[了解如何迁移](#migrating-a-simple-component-from-a-class-to-a-function) --- -### Adding state to a class component {/*adding-state-to-a-class-component*/} +### 向类组件添加 state {/*adding-state-to-a-class-component*/} -To add [state](/learn/state-a-components-memory) to a class, assign an object to a property called [`state`](#state). To update state, call [`this.setState`](#setstate). +为了向类组件添加 [state](/learn/state-a-components-memory) ,将一个对象分配给一个名为 [`state`](#state) 的属性。要更新 state ,请调用 [`this.setState`](#setstate) 。 @@ -1205,21 +1206,21 @@ button { display: block; margin-top: 10px; } -We recommend defining components as functions instead of classes. [See how to migrate.](#migrating-a-component-with-state-from-a-class-to-a-function) +我们建议将组件定义为函数而不是类。[了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function) --- -### Adding lifecycle methods to a class component {/*adding-lifecycle-methods-to-a-class-component*/} +### 向类组件中添加生命周期方法 {/*adding-lifecycle-methods-to-a-class-component*/} -There are a few special methods you can define on your class. +你可以在类中定义一些特殊方法。 -If you define the [`componentDidMount`](#componentdidmount) method, React will call it when your component is added *(mounted)* to the screen. React will call [`componentDidUpdate`](#componentdidupdate) after your component re-renders due to changed props or state. React will call [`componentWillUnmount`](#componentwillunmount) after your component has been removed *(unmounted)* from the screen. +如果你定义了 [`componentDidMount`](#componentdidmount) 方法,当你的组件被添加到屏幕上时,React 将会调用它。当你的组件由于 props 或 state 改变而重新渲染后,React 将调用 [`componentDidUpdate`](#componentdidupdate)。当你的组件从屏幕上被移除(**卸载**)后,React 将调用 [`componentWillUnmount`](#componentwillunmount)。 -If you implement `componentDidMount`, you usually need to implement all three lifecycles to avoid bugs. For example, if `componentDidMount` reads some state or props, you also have to implement `componentDidUpdate` to handle their changes, and `componentWillUnmount` to clean up whatever `componentDidMount` was doing. +如果你实现了 `componentDidMount` ,通常需要实现所有三个生命周期以避免错误。例如,如果 `componentDidMount` 读取某些 state 或属性,你还必须实现 `componentDidUpdate` 来处理它们的更改,并实现 `componentWillUnmount` 来清理 `componentDidMount`所执行的所有操作。 -For example, this `ChatRoom` component keeps a chat connection synchronized with props and state: +例如,这个 `ChatRoom` 组件使聊天连接与 props 和 state 保持同步: @@ -1316,7 +1317,7 @@ export default class ChatRoom extends Component { ```js chat.js export function createConnection(serverUrl, roomId) { - // A real implementation would actually connect to the server + // 真正的实现将实际地连接到服务器 return { connect() { console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); @@ -1335,21 +1336,21 @@ button { margin-left: 10px; } -Note that in development when [Strict Mode](/reference/react/StrictMode) is on, React will call `componentDidMount`, immediately call `componentWillUnmount`, and then call `componentDidMount` again. This helps you notice if you forgot to implement `componentWillUnmount` or if its logic doesn't fully "mirror" what `componentDidMount` does. +请注意,在开发中,当 [严格模式](/reference/react/StrictMode) 开启时,React 将在调用 `componentDidMount` 后,立即调用 `componentWillUnmount` ,然后再次调用 `componentDidMount` 。这可以帮助你注意到你是否忘记实现 `componentWillUnmount` ,或者它的逻辑是否没有完全“镜像覆盖到” `componentDidMount` 的作用。 -We recommend defining components as functions instead of classes. [See how to migrate.](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) +我们建议将组件定义为函数而不是类。[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) --- -### Catching rendering errors with an error boundary {/*catching-rendering-errors-with-an-error-boundary*/} +### 使用错误边界捕获渲染错误 {/*catching-rendering-errors-with-an-error-boundary*/} -By default, if your application throws an error during rendering, React will remove its UI from the screen. To prevent this, you can wrap a part of your UI into an *error boundary*. An error boundary is a special component that lets you display some fallback UI instead of the part that crashed--for example, an error message. +默认情况下,如果你的应用程序在渲染过程中抛出错误,React 将从屏幕上删除其 UI。为了防止这种情况,你可以将 UI 的一部分包装到 **错误边界** 中。错误边界是一个特殊的组件,可让你显示一些备用 UI ,而不是例如错误消息这样崩溃的部分。 -To implement an error boundary component, you need to provide [`static getDerivedStateFromError`](#static-getderivedstatefromerror) which lets you update state in response to an error and display an error message to the user. You can also optionally implement [`componentDidCatch`](#componentdidcatch) to add some extra logic, for example, to log the error to an analytics service. +要实现错误边界组件,你需要提供静态 getDerivedStateFromError ,它允许你更新状态以响应错误并向用户显示错误消息。你还可以选择实现 [`componentDidCatch`](#componentdidcatch) 以添加一些额外的逻辑,例如,将错误记录到分析服务。 ```js {7-10,12-19} class ErrorBoundary extends React.Component { @@ -1359,22 +1360,22 @@ class ErrorBoundary extends React.Component { } static getDerivedStateFromError(error) { - // Update state so the next render will show the fallback UI. + // 更新状态,以便下一次渲染将显示后备 UI。 return { hasError: true }; } componentDidCatch(error, info) { - // Example "componentStack": - // in ComponentThatThrows (created by App) - // in ErrorBoundary (created by App) - // in div (created by App) - // in App + // 示例“组件堆栈”: + // 在 ComponentThatThrows 中(由 App 创建) + // 在 ErrorBoundary 中(由 APP 创建) + // 在 div 中(由 APP 创建) + // 在 App 中 logErrorToMyService(error, info.componentStack); } render() { if (this.state.hasError) { - // You can render any custom fallback UI + // 您可以渲染任何自定义后备 UI return this.props.fallback; } @@ -1383,7 +1384,7 @@ class ErrorBoundary extends React.Component { } ``` -Then you can wrap a part of your component tree with it: +然后你可以用它包装组件树的一部分: ```js {1,3} Something went wrong

}> @@ -1391,25 +1392,25 @@ Then you can wrap a part of your component tree with it:
``` -If `Profile` or its child component throws an error, `ErrorBoundary` will "catch" that error, display a fallback UI with the error message you've provided, and send a production error report to your error reporting service. +如果 `Profile` 或其子组件抛出错误,`ErrorBoundary` 将“捕获”该错误,显示带有你提供的错误消息的后备 UI,并向你的错误报告服务发送生产错误报告。 -You don't need to wrap every component into a separate error boundary. When you think about the [granularity of error boundaries,](https://aweary.dev/fault-tolerance-react/) consider where it makes sense to display an error message. For example, in a messaging app, it makes sense to place an error boundary around the list of conversations. It also makes sense to place one around every individual message. However, it wouldn't make sense to place a boundary around every avatar. +你不需要将每个组件包装到单独的错误边界中。当你考虑[错误边界的布置](https://aweary.dev/fault-tolerance-react/)时,请考虑在哪里显示错误消息才有意义。例如,在消息传递应用程序中,在对话列表周围放置错误边界是有意义的。在每条单独的消息周围放置一个也是有意义的。然而,在每个头像周围设置边界是没有意义的。 -There is currently no way to write an error boundary as a function component. However, you don't have to write the error boundary class yourself. For example, you can use [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) instead. +目前还没有办法将错误边界编写为函数组件。但是,你不必自己编写错误边界类。例如,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 代替。 --- -## Alternatives {/*alternatives*/} +## 备选方案 {/*alternatives*/} -### Migrating a simple component from a class to a function {/*migrating-a-simple-component-from-a-class-to-a-function*/} +### 将简单的类组件迁移为函数式 {/*migrating-a-simple-component-from-a-class-to-a-function*/} -Typically, you will [define components as functions](/learn/your-first-component#defining-a-component) instead. +一般来说,你[将组件定义为函数](/learn/your-first-component#defining-a-component)。 -For example, suppose you're converting this `Greeting` class component to a function: +例如,假设你要将 `Greeting` 从类组件转换为函数: @@ -1435,23 +1436,22 @@ export default function App() { -Define a function called `Greeting`. This is where you will move the body of your `render` function. +定义一个名为 `Greeting` 的函数。你将移动 `render` 函数的主体到这里。 ```js function Greeting() { - // ... move the code from the render method here ... + // ... 把 render 方法中的代码移动到这里 ... } ``` -Instead of `this.props.name`, define the `name` prop [using the destructuring syntax](/learn/passing-props-to-a-component) and read it directly: - +定义 `name` 属性而不是 `this.props.name` ,[使用解构语法](/learn/passing-props-to-a-component) 来直接读取它: ```js function Greeting({ name }) { return

Hello, {name}!

; } ``` -Here is a complete example: +这里有个完整的例子: @@ -1475,7 +1475,7 @@ export default function App() { --- -### Migrating a component with state from a class to a function {/*migrating-a-component-with-state-from-a-class-to-a-function*/} +### 将具有状态的类组件迁移到函数 {/*migrating-a-component-with-state-from-a-class-to-a-function*/} Suppose you're converting this `Counter` class component to a function: @@ -1525,7 +1525,7 @@ button { display: block; margin-top: 10px; } -Start by declaring a function with the necessary [state variables:](/reference/react/useState#adding-state-to-a-component) +首先用必要的 [state variables](/reference/react/useState#adding-state-to-a-component) 来创建一个函数。 ```js {4-5} import { useState } from 'react'; @@ -1536,7 +1536,7 @@ function Counter() { // ... ``` -Next, convert the event handlers: +接下来,转换事件处理程序: ```js {5-7,9-11} function Counter() { @@ -1553,9 +1553,9 @@ function Counter() { // ... ``` -Finally, replace all references starting with `this` with the variables and functions you defined in your component. For example, replace `this.state.age` with `age`, and replace `this.handleNameChange` with `handleNameChange`. +最后,将所有以 `this` 开头的引用替换为你在组件中定义的变量和函数。例如,将 `this.state.age` 替换为 `age` ,将 `this.handleNameChange` 替换为 `handleNameChange` 。 -Here is a fully converted component: +这是一个完全转换后的组件: @@ -1597,9 +1597,9 @@ button { display: block; margin-top: 10px; } --- -### Migrating a component with lifecycle methods from a class to a function {/*migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function*/} +### 将具有生命周期方法的组件从类迁移到函数 {/*migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function*/} -Suppose you're converting this `ChatRoom` class component with lifecycle methods to a function: +假设你要将具有生命周期方法的 `ChatRoom` 类组件转换为函数: @@ -1696,7 +1696,7 @@ export default class ChatRoom extends Component { ```js chat.js export function createConnection(serverUrl, roomId) { - // A real implementation would actually connect to the server + // 真正的实现将实际连接到服务器 return { connect() { console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); @@ -1715,11 +1715,11 @@ button { margin-left: 10px; } -First, verify that your [`componentWillUnmount`](#componentwillunmount) does the opposite of [`componentDidMount`.](#componentdidmount) In the above example, that's true: it disconnects the connection that `componentDidMount` sets up. If such logic is missing, add it first. +首先,验证你的 [`componentWillUnmount`](#componentwillunmount) 是否与 [`componentDidMount`](#componentdidmount) 执行相反的操作。在上面的示例中操作是正确的:它会断开 `componentDidMount` 设置的连接。如果缺少这样的逻辑,请先添加它。 -Next, verify that your [`componentDidUpdate`](#componentdidupdate) method handles changes to any props and state you're using in `componentDidMount`. In the above example, `componentDidMount` calls `setupConnection` which reads `this.state.serverUrl` and `this.props.roomId`. This is why `componentDidUpdate` checks whether `this.state.serverUrl` and `this.props.roomId` have changed, and resets the connection if they did. If your `componentDidUpdate` logic is missing or doesn't handle changes to all relevant props and state, fix that first. +接下来, 验证你的 [`componentDidUpdate`](#componentdidupdate) 方法是否可以处理对 `componentDidMount` 中使用的任何 props 和 state 的更改。在上面的例子中,`componentDidMount` 调用 `setupConnection` 来读取 `this.state.serverUrl` 和 `this.props.roomId` 。这就是为什么 `componentDidUpdate` 检查 `this.state.serverUrl` 和 `this.props.roomId` 是否已更改,如果更改了则重置连接。 如果你的 `componentDidUpdate` 逻辑丢失或无法处理所有相关 props 和 state 的更改,请首先修复该问题。 -In the above example, the logic inside the lifecycle methods connects the component to a system outside of React (a chat server). To connect a component to an external system, [describe this logic as a single Effect:](/reference/react/useEffect#connecting-to-an-external-system) +在上面的示例中,生命周期方法内的逻辑将组件连接到 React 外部的系统(聊天服务器)。要将组件连接到外部系统,[将此逻辑描述为单个效果:](/reference/react/useEffect#connecting-to-an-external-system) ```js {6-12} import { useState, useEffect } from 'react'; @@ -1739,7 +1739,7 @@ function ChatRoom({ roomId }) { } ``` -This [`useEffect`](/reference/react/useEffect) call is equivalent to the logic in the lifecycle methods above. If your lifecycle methods do multiple unrelated things, [split them into multiple independent Effects.](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things) Here is a complete example you can play with: +这个 [`useEffect`](/reference/react/useEffect) 调用相当于上面生命周期方法中的逻辑。如果你的生命周期方法做了多个互不相关的事,[将它们分成多个独立的效果](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things)。这是一个你可以使用的完整示例: @@ -1805,7 +1805,7 @@ export default function ChatRoom({ roomId }) { ```js chat.js export function createConnection(serverUrl, roomId) { - // A real implementation would actually connect to the server + // 真正的实现将实际连接到服务器 return { connect() { console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); @@ -1826,15 +1826,15 @@ button { margin-left: 10px; } -If your component does not synchronize with any external systems, [you might not need an Effect.](/learn/you-might-not-need-an-effect) +如果你的组件不与任何外部系统同步,[你可能不需要 effect ](/learn/you-might-not-need-an-effect) --- -### Migrating a component with context from a class to a function {/*migrating-a-component-with-context-from-a-class-to-a-function*/} +### 将具有 context 的组件从类迁移到函数 {/*migrating-a-component-with-context-from-a-class-to-a-function*/} -In this example, the `Panel` and `Button` class components read [context](/learn/passing-data-deeply-with-context) from [`this.context`:](#context) +在这个例子中,`Panel` 和 `Button` 类组件从 [`this.context`:](#context) 读取 [context](/learn/passing-data-deeply-with-context)。 @@ -1928,7 +1928,7 @@ export default function MyApp() { -When you convert them to function components, replace `this.context` with [`useContext`](/reference/react/useContext) calls: +当你将它们转换为函数组件时,将 `this.context` 替换为 [`useContext`](/reference/react/useContext) 调用: From 7ac49dfa15e8967722583ec9e4232236488ed1f2 Mon Sep 17 00:00:00 2001 From: Tosuke <1848228664@qq.com> Date: Mon, 3 Jul 2023 12:20:46 +0800 Subject: [PATCH 02/13] chore: fix space error --- src/content/reference/react/Component.md | 168 +++++++++++------------ 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index b2d93c7781..ee07177b2b 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -73,7 +73,7 @@ class Button extends Component { -在类组件中读取 `this.context` 等同于在函数式组件中使用的 [`useContext`](/reference/react/useContext) 。 +在类组件中读取 `this.context` 等同于在函数式组件中使用的 [`useContext`](/reference/react/useContext)。 [了解如何迁移](#migrating-a-component-with-context-from-a-class-to-a-function) @@ -83,7 +83,7 @@ class Button extends Component { ### `props` {/*props*/} -传递给类组件的 props 的有效形式为 `this.props` 。 +传递给类组件的 props 的有效形式为 `this.props`。 ```js {3} class Greeting extends Component { @@ -97,7 +97,7 @@ class Greeting extends Component { -在类组件中读取 `this.props` 等同于在函数式组件中使用的 [declaring props](/learn/passing-props-to-a-component#step-2-read-props-inside-the-child-component) 。 +在类组件中读取 `this.props` 等同于在函数式组件中使用的 [声明式 props](/learn/passing-props-to-a-component#step-2-read-props-inside-the-child-component)。 [了解如何迁移](#migrating-a-simple-component-from-a-class-to-a-function) @@ -119,7 +119,7 @@ class Greeting extends Component { ### `state` {/*state*/} -使用 `this.state` 来访问一个类组件的 state 。 `state` 字段必须是一个对象。请不要直接改变 state 的值。如果你希望改变 state ,使用新的 state 来调用 `setState` 函数。 +使用 `this.state` 来访问一个类组件的 state。 `state` 字段必须是一个对象。请不要直接改变 state 的值。如果你希望改变 state,使用新的 state 来调用 `setState` 函数。 ```js {2-4,7-9,18} class Counter extends Component { @@ -148,7 +148,7 @@ class Counter extends Component { -在类组件中定义 `state` 等同于在函数式组件中通过调用 [`useState`](/reference/react/useState) 函数所创造的 state 。 +在类组件中定义 `state` 等同于在函数式组件中通过调用 [`useState`](/reference/react/useState) 函数所创造的 state。 [了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function) @@ -173,7 +173,7 @@ class Counter extends Component { } ``` -如果你使用更新的 JavaScript 语法的话,那么很少需要使用到 constructors 。相反,你可以使用现代浏览器和像 [Babel](https://babeljs.io/) 这样的工具都支持的[公有类字段语法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields)来重写上面的代码。 +如果你使用更新的 JavaScript 语法的话,那么很少需要使用到 constructors。相反,你可以使用现代浏览器和像 [Babel](https://babeljs.io/) 这样的工具都支持的[公有类字段语法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields)来重写上面的代码。 ```js {2,4} class Counter extends Component { @@ -188,7 +188,7 @@ constructor 不应该包含任何额外作用或者监听相关。 #### 参数 {/*constructor-parameters*/} -* `props`: 组件初始的 props 。 +* `props`: 组件初始的 props。 #### 返回值 {/*constructor-returns*/} @@ -198,9 +198,9 @@ constructor 不应该包含任何额外作用或者监听相关。 * 不要在 constructor 中运行任何任额外作用或者监听相关的代码。相反,我们使用 [`componentDidMount`](#componentdidmount) 来解决这个问题。 -* 在 constructor 中,你需要在其他声明之前调用 `super(props)` 。如果你不这样做,当 constructor 运行时 `this.props` 就会为 `undefined` , 这可能会让人迷惑并且导致错误。 +* 在 constructor 中,你需要在其他声明之前调用 `super(props)`。如果你不这样做,当 constructor 运行时 `this.props` 就会为 `undefined`, 这可能会让人迷惑并且导致错误。 -* Constructor 是唯一一个你能直接赋值 [`this.state`](#state) 的地方。 在其余所有方法中,你需要使用 [`this.setState()`](#setstate) 来代替。不要使用在 constructor 中使用 `setState` 。 +* Constructor 是唯一一个你能直接赋值 [`this.state`](#state) 的地方。 在其余所有方法中,你需要使用 [`this.setState()`](#setstate) 来代替。不要使用在 constructor 中使用 `setState`。 * 当你使用 [服务端渲染](/reference/react-dom/server) 时, constructor 也将在服务端运行,紧接着是 [`render`](#render) 方法。 然而,像是 `componentDidMount` 或者 `componentWillUnmount` 这样的生命周期方法将不会在服务端运行。 @@ -216,15 +216,15 @@ constructor 不应该包含任何额外作用或者监听相关。 ### `componentDidCatch(error, info)` {/*componentdidcatch*/} -如果你定义了 `componentDidCatch` ,那么当某些子组件(包括远程子组件)在渲染过程中抛出错误时React将调用它。这使得你可以在生产中将该错误记录到错误报告服务中。 +如果你定义了 `componentDidCatch`,那么当某些子组件(包括远程子组件)在渲染过程中抛出错误时React将调用它。这使得你可以在生产中将该错误记录到错误报告服务中。 -一般来说,它与 [`static getDerivedStateFromError`](#static-getderivedstatefromerror) 一起使用,这样做允许你更新状态以响应错误并向用户显示错误消息。具有这些方法的组件称为 **错误边界** 。 +一般来说,它与 [`static getDerivedStateFromError`](#static-getderivedstatefromerror) 一起使用,这样做允许你更新状态以响应错误并向用户显示错误消息。具有这些方法的组件称为 **错误边界**。 [查看示例](#catching-rendering-errors-with-an-error-boundary) #### 参数 {/*componentdidcatch-parameters*/} -* `error`: 抛出的错误。实际上,它通常会是一个 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,不过这并不能保证,因为 JavaScript 允许 [`throw`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 所有的值,包括字符串甚至是 `null` 。 +* `error`: 抛出的错误。实际上,它通常会是一个 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,不过这并不能保证,因为 JavaScript 允许 [`throw`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 所有的值,包括字符串甚至是 `null`。 * `info`: 一个包含有关错误的附加信息的对象。 它的 `componentStack` 字段包含一个堆栈跟踪,其中包含抛出的组件,以及其所有父组件的名称和源位置。在生产中,组件名称将被缩小。如果你设置了生产错误报告,则可以使用源映射来解码组件堆栈,就像处理常规 JavaScript 错误堆栈一样。 @@ -234,13 +234,13 @@ constructor 不应该包含任何额外作用或者监听相关。 #### 说明 {/*componentdidcatch-caveats*/} -* 在以前, 经常在 `componentDidCatch` 中使用 `setState` 来更新UI以及显示回退错误消息。这已被废弃,有利于定义 [`static getDerivedStateFromError`.](#static-getderivedstatefromerror) 。 +* 在以前, 经常在 `componentDidCatch` 中使用 `setState` 来更新UI以及显示回退错误消息。这已被废弃,有利于定义 [`static getDerivedStateFromError`.](#static-getderivedstatefromerror)。 -* React 的生产和开发版本在 `componentDidCatch` 处理错误的方式有所不同,在开发环境下,错误将冒泡至 `window` ,这意味着任何 `window.onerror` 或者 `window.addEventListener('error', callback)` 都将拦截被 `componentDidCatch` 所捕获到的错误。在生产环境下,相反,错误并不会冒泡, 这意味着任何祖先级的错误处理器都只会接收到被 `componentDidCatch` 捕获的非显式错误。 +* React 的生产和开发版本在 `componentDidCatch` 处理错误的方式有所不同,在开发环境下,错误将冒泡至 `window`,这意味着任何 `window.onerror` 或者 `window.addEventListener('error', callback)` 都将拦截被 `componentDidCatch` 所捕获到的错误。在生产环境下,相反,错误并不会冒泡, 这意味着任何祖先级的错误处理器都只会接收到被 `componentDidCatch` 捕获的非显式错误。 -在函数组件中目前还没有直接等价的 `componentDidCatch` 。如果你想要避免创建类组件,那么可以单独写一个像上面一样的 `ErrorBoundary` 并在整个应用中使用它。 又或者,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包,它可以完成同样的工作。 +在函数组件中目前还没有直接等价的 `componentDidCatch`。如果你想要避免创建类组件,那么可以单独写一个像上面一样的 `ErrorBoundary` 并在整个应用中使用它。 又或者,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包,它可以完成同样的工作。 @@ -250,7 +250,7 @@ constructor 不应该包含任何额外作用或者监听相关。 如果你定义了 `componentDidMount` 方法, React 将会在你的组件添加上屏幕 **(mounted)** 时调用它。这是开始数据获取、设置监听或操作DOM节点的常见位置。 -如果你要执行 `componentDidMount` ,你通常需要设置一些其他的生命周期函数来避免出错。例如,如果 `componentDidMount` 读取一些 state 或者 props ,你还必须要设置 [`componentDidUpdate`](#componentdidupdate) 来处理它们的更改, 以及设置 [`componentWillUnmount`](#componentwillunmount) 来清理 `componentDidMount` 所产生的作用。 +如果你要执行 `componentDidMount`,你通常需要设置一些其他的生命周期函数来避免出错。例如,如果 `componentDidMount` 读取一些 state 或者 props,你还必须要设置 [`componentDidUpdate`](#componentdidupdate) 来处理它们的更改, 以及设置 [`componentWillUnmount`](#componentwillunmount) 来清理 `componentDidMount` 所产生的作用。 ```js {6-8} class ChatRoom extends Component { @@ -292,13 +292,13 @@ class ChatRoom extends Component { #### 说明 {/*componentdidmount-caveats*/} -- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发环境中 React 会调用 `componentDidMount`,然后会立刻调用 [`componentWillUnmount`,](#componentwillunmount) 接着再次调用 `componentDidMount` 。 这将帮助你注意到你是否忘记设置 `componentWillUnmount` 或者它的逻辑是否完全覆盖到 `componentDidMount` 的功能。 +- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发环境中 React 会调用 `componentDidMount`,然后会立刻调用 [`componentWillUnmount`,](#componentwillunmount) 接着再次调用 `componentDidMount`。 这将帮助你注意到你是否忘记设置 `componentWillUnmount` 或者它的逻辑是否完全覆盖到 `componentDidMount` 的功能。 -- 虽然你可以在 `componentDidMount` 中立即调用[`setState`](#setstate) ,不过最好避免这样做。 这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。 这确认了在这种情况下即使 [`render`](#render) 被调用了两次, 用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下, 你应该能在[`constructor`](#constructor)中设置初始的 state 。 但是,对于模态和工具提示等情况,当你需要在呈现依赖于其大小或位置的内容之前测量 DOM 节点时,它可能是必要的。 +- 虽然你可以在 `componentDidMount` 中立即调用[`setState`](#setstate),不过最好避免这样做。 这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。 这确认了在这种情况下即使 [`render`](#render) 被调用了两次, 用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下, 你应该能在[`constructor`](#constructor)中设置初始的 state。 但是,对于模态和工具提示等情况,当你需要在呈现依赖于其大小或位置的内容之前测量 DOM 节点时,它可能是必要的。 -对于大多数的使用场景来说,在类组件中一起定义 `componentDidMount`, `componentDidUpdate`, 和 `componentWillUnmount` 等同于在函数式组件中调用 [`useEffect`](/reference/react/useEffect) 。在一些少数的情况,例如在浏览器绘制前执行代码很重要时, [`useLayoutEffect`](/reference/react/useLayoutEffect) 是一个更合适的匹配。 +对于大多数的使用场景来说,在类组件中一起定义 `componentDidMount`, `componentDidUpdate`, 和 `componentWillUnmount` 等同于在函数式组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时, [`useLayoutEffect`](/reference/react/useLayoutEffect) 是一个更合适的匹配。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) @@ -310,7 +310,7 @@ class ChatRoom extends Component { 如果你定义了 `componentDidUpdate` 方法,当你的组件更新了 props 或 state 重新渲染后,React 将立即调用它。这个方法不会在首次渲染时调用。 -你可以在更新后使用它来操作 DOM 。这也是进行网络请求的常见位置,只要你将当前的 props 与以前的 props 进行比较即可(例如,如果 props 没有更改,则可能不需要网络请求)。一般来说, 这个方法与[`componentDidMount`](#componentdidmount) 以及 [`componentWillUnmount`:](#componentwillunmount) 一起使用。 +你可以在更新后使用它来操作 DOM。这也是进行网络请求的常见位置,只要你将当前的 props 与以前的 props 进行比较即可(例如,如果 props 没有更改,则可能不需要网络请求)。一般来说, 这个方法与[`componentDidMount`](#componentdidmount) 以及 [`componentWillUnmount`:](#componentwillunmount) 一起使用。 ```js {10-18} class ChatRoom extends Component { @@ -345,11 +345,11 @@ class ChatRoom extends Component { #### 参数 {/*componentdidupdate-parameters*/} -* `prevProps`: 更新之前的 Props 。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`: 更新之前的 Props。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: 更新之前的 State 。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`: 更新之前的 State。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 -* `snapshot`: 如果你设置了 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) ,那么 `snapshot` 将包含从该方法返回的值。否则,它将是 `undefined` 。 +* `snapshot`: 如果你设置了 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),那么 `snapshot` 将包含从该方法返回的值。否则,它将是 `undefined`。 #### 返回值 {/*componentdidupdate-returns*/} @@ -361,11 +361,11 @@ class ChatRoom extends Component { - `componentDidUpdate` 内部的逻辑通常应该包含在比较 `this.props` 与 `prevProps` 和 `this.state` 与 `prevState` 之中。 否则,就会存在创建无限循环的风险。 -- 虽然可以在 `componentDidUpdate` 中立即调用 [`setState`](#setstate) ,但最好尽可能避免这样做。它将触发一个额外的渲染,但它将在浏览器更新屏幕之前发生。 这导致了即使 [`render`](#render) 在这种情况下会被调用两次, 用户也不会看到中间状态。这种模式通常会导致性能问题,但在模态和工具提示等少数情况下,当你需要在呈现依赖于其大小或位置的内容之前测量DOM节点时,可能需要使用这种模式。 +- 虽然可以在 `componentDidUpdate` 中立即调用 [`setState`](#setstate),但最好尽可能避免这样做。它将触发一个额外的渲染,但它将在浏览器更新屏幕之前发生。 这导致了即使 [`render`](#render) 在这种情况下会被调用两次, 用户也不会看到中间状态。这种模式通常会导致性能问题,但在模态和工具提示等少数情况下,当你需要在呈现依赖于其大小或位置的内容之前测量DOM节点时,可能需要使用这种模式。 -对于大多数用例来说, 在类组件中一起定义 `componentDidMount` , `componentDidUpdate` , 和 `componentWillUnmount` 相当于在函数式组件中定义了 [`useEffect`](/reference/react/useEffect) 。在少数情况下,代码在浏览器绘制之前运行很重要,这时 [`useLayoutEffect`](/reference/react/useLayoutEffect) 是更佳的匹配。 +对于大多数用例来说, 在类组件中一起定义 `componentDidMount`, `componentDidUpdate`, 和 `componentWillUnmount` 相当于在函数式组件中定义了 [`useEffect`](/reference/react/useEffect)。在少数情况下,代码在浏览器绘制之前运行很重要,这时 [`useLayoutEffect`](/reference/react/useLayoutEffect) 是更佳的匹配。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) @@ -376,7 +376,7 @@ class ChatRoom extends Component { -此 API 已从 `componentWillMount` 重命名为 [`UNSAFE_componentWillMount`.](#unsafe_componentwillmount) ,旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 +此 API 已从 `componentWillMount` 重命名为 [`UNSAFE_componentWillMount`.](#unsafe_componentwillmount),旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -388,7 +388,7 @@ class ChatRoom extends Component { -此 API 已从 `componentWillReceiveProps` 重命名为 [`UNSAFE_componentWillReceiveProps`.](#unsafe_componentwillreceiveprops) ,旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 +此 API 已从 `componentWillReceiveProps` 重命名为 [`UNSAFE_componentWillReceiveProps`.](#unsafe_componentwillreceiveprops),旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -400,7 +400,7 @@ class ChatRoom extends Component { -此 API 已从 `componentWillUpdate` 重命名为 [`UNSAFE_componentWillUpdate`.](#unsafe_componentwillupdate) ,旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 +此 API 已从 `componentWillUpdate` 重命名为 [`UNSAFE_componentWillUpdate`.](#unsafe_componentwillupdate),旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -412,7 +412,7 @@ class ChatRoom extends Component { 如果你定义了 `componentWillUnmount` 方法,React 会在你的组件被移除屏幕之前 *(unmounted)* 调用它。这是取消数据获取或删除监听的常见位置。 -`componentWillUnmount` 内部的逻辑应该覆盖全 [`componentDidMount`.](#componentdidmount) 内部的逻辑, 例如,如果在 `componentDidMount` 中设置了一个监听,那么 `componentWillUnmount` 中应该清除掉这个监听。如果你 `componentWillUnmount` 的清理逻辑中读取了一些 props 或者 state ,那么你通常还需要实现一个 [`componentDidUpdate`](#componentdidupdate) 来清理旧 props 和 state 对应的资源(例如监听)。 +`componentWillUnmount` 内部的逻辑应该覆盖全 [`componentDidMount`.](#componentdidmount) 内部的逻辑, 例如,如果在 `componentDidMount` 中设置了一个监听,那么 `componentWillUnmount` 中应该清除掉这个监听。如果你 `componentWillUnmount` 的清理逻辑中读取了一些 props 或者 state,那么你通常还需要实现一个 [`componentDidUpdate`](#componentdidupdate) 来清理旧 props 和 state 对应的资源(例如监听)。 ```js {20-22} class ChatRoom extends Component { @@ -454,11 +454,11 @@ class ChatRoom extends Component { #### 说明 {/*componentwillunmount-caveats*/} -- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发中React会调用[`componentDidMount`,](#componentdidmount),然后立即调用 `componentWillUnmount` ,然后再次调用 `componentDidMount` 。这可以帮助你注意到你是否忘记实现 `componentWillUnmount` ,或者它的逻辑是否没有完全覆盖到 `componentDidMount` 的作用。 +- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发中React会调用[`componentDidMount`,](#componentdidmount),然后立即调用 `componentWillUnmount`,然后再次调用 `componentDidMount`。这可以帮助你注意到你是否忘记实现 `componentWillUnmount`,或者它的逻辑是否没有完全覆盖到 `componentDidMount` 的作用。 -对于许多用例,在类组件中一起定义 `componentDidMount` 、 `componentDidUpdate` 和 `componentWillUnmount` 相当于在函数式组件中调用 [`useEffect`](/reference/react/useEffect) 。在少数情况下,代码在浏览器绘制之前运行很重要时,[`useLayoutEffect`](/reference/react/useLayoutEffect) 是更为接近的匹配。 +对于许多用例,在类组件中一起定义 `componentDidMount` 、 `componentDidUpdate` 和 `componentWillUnmount` 相当于在函数式组件中调用 [`useEffect`](/reference/react/useEffect)。在少数情况下,代码在浏览器绘制之前运行很重要时,[`useLayoutEffect`](/reference/react/useLayoutEffect) 是更为接近的匹配。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) @@ -472,11 +472,11 @@ class ChatRoom extends Component { 通常来说,这是没有必要的。如果组件的 [`render`](#render) 方法仅读取了 [`this.props`](#props) 、 [`this.state`](#state) 或 [`this.context`,]( #context) 时,当你在组件或其父组件之一内调用 [`setState`](#setstate) 时,它就将自动重新渲染。但是,如果组件的 `render` 方法直接从外部数据源读取,则必须告诉 React 在该数据源更改时更新用户界面。这就是你可以用 `forceUpdate` 做的事。 -尽量避免使用 `forceUpdate` 并且在 `render` 中只读取 `this.props` 和 `this.state` 。 +尽量避免使用 `forceUpdate` 并且在 `render` 中只读取 `this.props` 和 `this.state`。 #### 参数 {/*forceupdate-parameters*/} -* **optional** `callback` 如果有指定,React 将在提交更新后调用你提供的 `callback` 。 +* **optional** `callback` 如果有指定,React 将在提交更新后调用你提供的 `callback`。 #### 返回值 {/*forceupdate-returns*/} @@ -508,7 +508,7 @@ class ChatRoom extends Component { ### `getSnapshotBeforeUpdate(prevProps, prevState)` {/*getsnapshotbeforeupdate*/} -如果你实现 `getSnapshotBeforeUpdate` ,React 会在 React 更新 DOM 之前立即调用它。它使你的组件能够在 DOM 发生更改之前捕获一些信息(例如滚动位置)。此生命周期方法返回的任何值都将作为参数传递给 [`componentDidUpdate`。](#componentdidupdate) +如果你实现 `getSnapshotBeforeUpdate`,React 会在 React 更新 DOM 之前立即调用它。它使你的组件能够在 DOM 发生更改之前捕获一些信息(例如滚动位置)。此生命周期方法返回的任何值都将作为参数传递给 [`componentDidUpdate`。](#componentdidupdate) 例如,你可以在 UI 中像是需要在更新期间保留其滚动位置的聊天消息来使用它。 @@ -551,17 +551,17 @@ class ScrollingList extends React.Component { #### 参数 {/*getsnapshotbeforeupdate-parameters*/} -* `prevProps`: 更新之前的 Props 。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`: 更新之前的 Props。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: 更新之前的 State 。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`: 更新之前的 State。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 #### 返回值 {/*getsnapshotbeforeupdate-returns*/} -你应该返回你想要的任何类型的快照值,或者 `null` 。你返回的值将作为第三个参数传递给 [`componentDidUpdate`。](#componentdidupdate) 。 +你应该返回你想要的任何类型的快照值,或者 `null`。你返回的值将作为第三个参数传递给 [`componentDidUpdate`。](#componentdidupdate)。 #### 说明 {/*getsnapshotbeforeupdate-caveats*/} -- 如果定义了 [`shouldComponentUpdate`](#shouldcomponentUpdate) 并返回了 `false` ,则不会调用 `getSnapshotBeforeUpdate` 。 +- 如果定义了 [`shouldComponentUpdate`](#shouldcomponentUpdate) 并返回了 `false`,则不会调用 `getSnapshotBeforeUpdate`。 @@ -587,15 +587,15 @@ class Greeting extends Component { } ``` -React 可能随时调用 `render` ,因此你不应该假设它在特定时间运行。通常, `render` 方法应该返回一段 [JSX](/learn/writing-markup-with-jsx),但也支持一些 [其他返回类型](#render-returns)(如字符串)。为了计算返回的 JSX ,`render` 方法可以读取 [`this.props`](#props)、[`this.state`](#state) 和 [`this.context`](#context) 。 +React 可能随时调用 `render`,因此你不应该假设它在特定时间运行。通常, `render` 方法应该返回一段 [JSX](/learn/writing-markup-with-jsx),但也支持一些 [其他返回类型](#render-returns)(如字符串)。为了计算返回的 JSX,`render` 方法可以读取 [`this.props`](#props)、[`this.state`](#state) 和 [`this.context`](#context)。 你应该将 `render` 方法编写为纯函数,这意味着如果 props、state 和 context 相同,它应该返回相同的结果。它也不应该包含额外的作用(例如设置监听)或与浏览器 API 交互。额外的作用应该发生在事件处理程序或 [`componentDidMount`.](#componentdidmount) 等方法中。 #### 参数 {/*render-parameters*/} -* `prevProps`: 更新之前的 Props 。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`: 更新之前的 Props。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: 更新之前的 State 。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`: 更新之前的 State。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 #### 返回值 {/*render-returns*/} @@ -615,7 +615,7 @@ React 可能随时调用 `render` ,因此你不应该假设它在特定时间 ### `setState(nextState, callback?)` {/*setstate*/} -调用 `setState` 来更新 React 组件的 state 。 +调用 `setState` 来更新 React 组件的 state。 ```js {8-10} class Form extends Component { @@ -657,11 +657,11 @@ function handleClick() { } ``` -它只影响从 **下一个** 渲染开始返回的 `this.state` 。 +它只影响从 **下一个** 渲染开始返回的 `this.state`。 -你还可以将函数传递给 `setState` 。它允许你根据先前的 state 来更新 state: +你还可以将函数传递给 `setState`。它允许你根据先前的 state 来更新 state: ```js {2-6} handleIncreaseAge = () => { @@ -678,10 +678,10 @@ function handleClick() { #### 参数 {/*setstate-parameters*/} * `nextState`: 一个对象或者函数。 - * 如果你传递一个对象作为 `nextState` ,它将浅层合并到 `this.state` 中。 - * 如果你传递一个函数作为 `nextState` ,它将被视为 **更新函数** 。它必须是个纯函数,应该以已加载的 state 和 props 作为参数,并且应该返回要浅层合并到 `this.state` 中的对象。 React 会将你的更新函数放入队列中并重新渲染你的组件。在下一次渲染期间,React 将通过应用队列中的所有更新程序来计算下一个 state 。 + * 如果你传递一个对象作为 `nextState`,它将浅层合并到 `this.state` 中。 + * 如果你传递一个函数作为 `nextState`,它将被视为 **更新函数**。它必须是个纯函数,应该以已加载的 state 和 props 作为参数,并且应该返回要浅层合并到 `this.state` 中的对象。 React 会将你的更新函数放入队列中并重新渲染你的组件。在下一次渲染期间,React 将通过应用队列中的所有更新程序来计算下一个 state。 -* **可选的** `callback`: 如果指定,React 将在提交更新后调用你提供的 `回调` 。 +* **可选的** `callback`: 如果指定,React 将在提交更新后调用你提供的 `回调`。 #### 返回值 {/*setstate-returns*/} @@ -689,13 +689,13 @@ function handleClick() { #### 说明 {/*setstate-caveats*/} -- 将 `setState` 视为 **请求** ,而不是立即会更新组件的命令。当多个组件更新它们的 state 以响应事件时, React 将批量更新它们,并在这次事件结束时将它们一起重新渲染。在极少数情况下,你需要强制同步应用特定的状态更新,你可以将其包装在 [`flushSync`,](/reference/react-dom/flushSync) 中,但这可能会损害性能。 +- 将 `setState` 视为 **请求**,而不是立即会更新组件的命令。当多个组件更新它们的 state 以响应事件时, React 将批量更新它们,并在这次事件结束时将它们一起重新渲染。在极少数情况下,你需要强制同步应用特定的状态更新,你可以将其包装在 [`flushSync`,](/reference/react-dom/flushSync) 中,但这可能会损害性能。 -- `setState` 不会立即更新 `this.state`。这让在调用 `setState` 之后立即读取 `setState` 成为一个潜在的陷阱。相反,请使用 [`componentDidUpdate`](#componentdidupdate) 或 setState `callback` 参数,其中任何一个都保证在更新后触发。如果需要根据前一个状态来设置状态,可以将函数传递给 `nextState` ,如上所述。 +- `setState` 不会立即更新 `this.state`。这让在调用 `setState` 之后立即读取 `setState` 成为一个潜在的陷阱。相反,请使用 [`componentDidUpdate`](#componentdidupdate) 或 setState `callback` 参数,其中任何一个都保证在更新后触发。如果需要根据前一个状态来设置状态,可以将函数传递给 `nextState`,如上所述。 -在类组件中调用 `setState` 等同于在函数式组件中调用 [`set` 函数](/reference/react/useState#setstate) 。 +在类组件中调用 `setState` 等同于在函数式组件中调用 [`set` 函数](/reference/react/useState#setstate)。 [了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function) @@ -705,7 +705,7 @@ function handleClick() { ### `shouldComponentUpdate(nextProps, nextState, nextContext)` {/*shouldcomponentupdate*/} -如果你定义了 `shouldComponentUpdate` ,React 将调用它来确定是否可以跳过重新渲染。 +如果你定义了 `shouldComponentUpdate`,React 将调用它来确定是否可以跳过重新渲染。 如果你确信你想手动编写它,你可以将`this.props`与`nextProps`进行比较,将`this.state`与`nextState`进行比较,并返回`false`来告诉React可以跳过更新。 @@ -734,12 +734,12 @@ class Rectangle extends Component { ``` -当收到新的 props 或 state 时,React 会在渲染之前调用 `shouldComponentUpdate` ,默认为 `true` 。初始渲染或使用 [`forceUpdate`](#forceupdate) 时将不会调用此方法。 +当收到新的 props 或 state 时,React 会在渲染之前调用 `shouldComponentUpdate`,默认为 `true`。初始渲染或使用 [`forceUpdate`](#forceupdate) 时将不会调用此方法。 #### 参数 {/*shouldcomponentupdate-parameters*/} -- `nextProps`: 组件即将用来渲染的下一个 props 。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 -- `nextState`: 组件即将渲染的下一个 state 。将 `nextState` 与 [`this.state`](#props) 进行比较以确定发生了什么变化。 +- `nextProps`: 组件即将用来渲染的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 +- `nextState`: 组件即将渲染的下一个 state。将 `nextState` 与 [`this.state`](#props) 进行比较以确定发生了什么变化。 - `nextContext`: 组件将要渲染的下一个上下文。将 `nextContext` 与 [`this.context`](#context) 进行比较以确定发生了什么变化。仅当你指定了 [`static contextType`](#static-contexttype)(更新的)或 [`static contextTypes`](#static-contexttypes)(旧版)时才可用。 #### 返回值 {/*shouldcomponentupdate-returns*/} @@ -752,9 +752,9 @@ class Rectangle extends Component { - 此方法 **仅仅** 作为性能优化而存在。如果你的组件在没有它的情况下损坏,请先修复组件。 -- 可以考虑使用 [`PureComponent`](/reference/react/PureComponent) 而不是手动编写 `shouldComponentUpdate` 。 `PureComponent` 浅层比较 props 和 state ,并减少你跳过必要更新的机会。 +- 可以考虑使用 [`PureComponent`](/reference/react/PureComponent) 而不是手动编写 `shouldComponentUpdate`。 `PureComponent` 浅层比较 props 和 state,并减少你跳过必要更新的机会。 -- 我们不建议在 `shouldComponentUpdate` 中进行深度相等检查或使用 `JSON.stringify` 。它使性能变得不可预测,并且依赖于每个 prop 和 state 的数据结构。在最好的情况下,你可能会冒着给应用程序引入多秒停顿的风险,而在最坏的情况下,你可能会面临使应用程序崩溃的风险。 +- 我们不建议在 `shouldComponentUpdate` 中进行深度相等检查或使用 `JSON.stringify`。它使性能变得不可预测,并且依赖于每个 prop 和 state 的数据结构。在最好的情况下,你可能会冒着给应用程序引入多秒停顿的风险,而在最坏的情况下,你可能会面临使应用程序崩溃的风险。 - 返回 `false` 并不会阻止子组件在 **他们的** state 发生变化时重新渲染。 @@ -770,11 +770,11 @@ class Rectangle extends Component { ### `UNSAFE_componentWillMount()` {/*unsafe_componentwillmount*/} -如果你定义了 `UNSAFE_componentWillMount` ,React 会在 [`constructor`](#constructor) 之后立即调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反,请使用一种替代方案: +如果你定义了 `UNSAFE_componentWillMount`,React 会在 [`constructor`](#constructor) 之后立即调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反,请使用一种替代方案: -- 要初始化状态,请将 [`state`](#state) 声明为类字段或在 [`constructor`.](#constructor) 内设置 `this.state` 。 +- 要初始化状态,请将 [`state`](#state) 声明为类字段或在 [`constructor`.](#constructor) 内设置 `this.state`。 -- 如果你需要运行额外作用或设置监听,请将该逻辑移至 [`componentDidMount`](#componentdidmount) 。 +- 如果你需要运行额外作用或设置监听,请将该逻辑移至 [`componentDidMount`](#componentdidmount)。 [查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples) @@ -796,7 +796,7 @@ class Rectangle extends Component { -在类组件中的 `UNSAFE_componentWillMount` 内部调用 [`setState`](#setstate) 来初始化状态等同于函数式组件中用该 state 作为初始状态传递给 [`useState`] 。 +在类组件中的 `UNSAFE_componentWillMount` 内部调用 [`setState`](#setstate) 来初始化状态等同于函数式组件中用该 state 作为初始状态传递给 [`useState`]。 @@ -805,7 +805,7 @@ class Rectangle extends Component { ### `UNSAFE_componentWillReceiveProps(nextProps, nextContext)` {/*unsafe_componentwillreceiveprops*/} -如果你定义了 `UNSAFE_componentWillReceiveProps` ,React 会在组件收到新的 props 时调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反,请使用以下替代方案: +如果你定义了 `UNSAFE_componentWillReceiveProps`,React 会在组件收到新的 props 时调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反,请使用以下替代方案: - 如果你需要 **运行额外作用** (例如,获取数据、运行动画或重新初始化监听)来响应 prop 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate) - 如果你需要 **避免仅在 prop 更改时重新计算某些数据** 请使用 [memoization helper](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization) 代替。 @@ -827,11 +827,11 @@ class Rectangle extends Component { - 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`.](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillReceiveProps` -- 即使它的名字是这样的, 如果你的应用程序使用 [`Suspense`.](/reference/react/Sus​​pense) 等现代 React 功能,`UNSAFE_componentWillReceiveProps` 不保证组件 **将** 接收这些 Props (例如,因为某些子组件的代码尚未加载), React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。 到下一次渲染尝试时,Props 可能会有所不同。这就是为什么这种方法 **不安全** 。仅为提交更新(例如重置监听)的代码应放入 [`componentDidUpdate`.](#componentdidupdate) +- 即使它的名字是这样的, 如果你的应用程序使用 [`Suspense`.](/reference/react/Sus​​pense) 等现代 React 功能,`UNSAFE_componentWillReceiveProps` 不保证组件 **将** 接收这些 Props (例如,因为某些子组件的代码尚未加载), React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。 到下一次渲染尝试时,Props 可能会有所不同。这就是为什么这种方法 **不安全**。仅为提交更新(例如重置监听)的代码应放入 [`componentDidUpdate`.](#componentdidupdate) -- `UNSAFE_componentWillReceiveProps` 并不意味着组件收到了与上次 **不同的** props 。你需要自己比较 `nextProps` 和 `this.props` 以检查是否发生了变化。 +- `UNSAFE_componentWillReceiveProps` 并不意味着组件收到了与上次 **不同的** props。你需要自己比较 `nextProps` 和 `this.props` 以检查是否发生了变化。 -- React 在挂载期间不会使用初始 props 调用 `UNSAFE_componentWillReceiveProps` 。仅当组件的某些属性要更新时,它才会调用此方法。例如,在同一组件内调用 [`setState`](#setstate) 通常不会触发 `UNSAFE_componentWillReceiveProps`。 +- React 在挂载期间不会使用初始 props 调用 `UNSAFE_componentWillReceiveProps`。仅当组件的某些属性要更新时,它才会调用此方法。例如,在同一组件内调用 [`setState`](#setstate) 通常不会触发 `UNSAFE_componentWillReceiveProps`。 @@ -846,7 +846,7 @@ class Rectangle extends Component { 如果你定义了`UNSAFE_componentWillUpdate`,React 会在使用新的 props 或 state 渲染之前调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反,请使用下面的替代方案: -- 如果你需要运行额外作用(例如,获取数据、运行动画或重新初始化监听)来响应 prop 或 state 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate) 。 +- 如果你需要运行额外作用(例如,获取数据、运行动画或重新初始化监听)来响应 prop 或 state 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate)。 - 如果需要从 DOM 中读取一些信息(例如,保存当前滚动位置)以便稍后在 [`componentDidUpdate`](#componentdidupdate) 中使用的话,那么请在 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 中读取。 [查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples) @@ -855,7 +855,7 @@ class Rectangle extends Component { - `nextProps`: 组件即将用来渲染的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 -- `nextState`: 组件即将渲染的下一个 state 。将 `nextState` 与 [`this.state`](#state) 进行比较以确定发生了什么变化。 +- `nextState`: 组件即将渲染的下一个 state。将 `nextState` 与 [`this.state`](#state) 进行比较以确定发生了什么变化。 #### 返回值 {/*unsafe_componentwillupdate-returns*/} @@ -873,7 +873,7 @@ class Rectangle extends Component { - `UNSAFE_componentWillUpdate` 并不意味着组件收到了与上次不同的 props 或状态。你需要自己将 `nextProps` 与 `this.props` 以及 `nextState` 与 `this.state` 进行比较,以检查是否发生了变化。 -- React 在挂载期间不会使用初始 props 和 state 调用 `UNSAFE_componentWillUpdate` 。 +- React 在挂载期间不会使用初始 props 和 state 调用 `UNSAFE_componentWillUpdate`。 函数式组件中没有与 `UNSAFE_componentWillUpdate` 直接dewng'tong的东西。 @@ -908,7 +908,7 @@ class Rectangle extends Component { ### `static contextType` {/*static-contexttype*/} -如果你想从类组件中读取 [`this.context`](#context-instance-field),则必须指定它需要读取哪个 context 。你指定为 `static contextType` 的上下文必须是之前由 [`createContext` 创建的值。](/reference/react/createContext) +如果你想从类组件中读取 [`this.context`](#context-instance-field),则必须指定它需要读取哪个 context。你指定为 `static contextType` 的上下文必须是之前由 [`createContext` 创建的值。](/reference/react/createContext) ```js {2} class Button extends Component { @@ -928,7 +928,7 @@ class Button extends Component { -在类组件中读取 `this.context` 等同于在函数组件中读取 [`useContext`](/reference/react/useContext) 。 +在类组件中读取 `this.context` 等同于在函数组件中读取 [`useContext`](/reference/react/useContext)。 [了解如何迁移](#migrating-a-component-with-context-from-a-class-to-a-function) @@ -938,7 +938,7 @@ class Button extends Component { ### `static defaultProps` {/*static-defaultprops*/} -你可以定义 `static defaultProps` 来设置类的默认 props 。它们将在props为 `undefined` 和缺少时使用 ,但不能用于 props 为 `null` 时 。 +你可以定义 `static defaultProps` 来设置类的默认 props。它们将在props为 `undefined` 和缺少时使用,但不能用于 props 为 `null` 时。 例如,以下是如何定义 `color` 属性默认为 `blue` : @@ -954,7 +954,7 @@ class Button extends Component { } ``` -如果未提供 `color` props 或者为 `undefined` ,它将默认设置为 `blue` : +如果未提供 `color` props 或者为 `undefined`,它将默认设置为 `blue` : ```js <> @@ -1038,9 +1038,9 @@ class Greeting extends React.Component { ### `static getDerivedStateFromProps(props, state)` {/*static-getderivedstatefromprops*/} -如果你定义了 `static getDerivedStateFromProps` ,React 会在初始挂载和后续更新时调用 [`render`](#render) 之前调用它。它应该返回一个对象来更新状态,或者返回 `null` 不更新任何内容。 +如果你定义了 `static getDerivedStateFromProps`,React 会在初始挂载和后续更新时调用 [`render`](#render) 之前调用它。它应该返回一个对象来更新状态,或者返回 `null` 不更新任何内容。 -此方法适用于[少数罕见用例](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state) ,其中 state 取决于 props 随着时间的推移的变化。例如,当 `userID` 属性更改时,此 `Form` 组件会重置 `email` 状态: +此方法适用于[少数罕见用例](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state),其中 state 取决于 props 随着时间的推移的变化。例如,当 `userID` 属性更改时,此 `Form` 组件会重置 `email` 状态: ```js {7-18} class Form extends Component { @@ -1079,8 +1079,8 @@ class Form extends Component { #### 参数 {/*static-getderivedstatefromprops-parameters*/} -- `props`: 组件即将用来渲染的下一个 props 。 -- `state`: 组件即将渲染的下一个 state 。 +- `props`: 组件即将用来渲染的下一个 props。 +- `state`: 组件即将渲染的下一个 state。 #### 返回值 {/*static-getderivedstatefromprops-returns*/} @@ -1118,7 +1118,7 @@ class Greeting extends Component { 每当 React 需要确定屏幕上显示的内容时,它就会调用你的 [`render`](#render) 方法。一般来说,你将让它返回一些 [JSX](/learn/writing-markup-with-jsx) 你的 `render` 方法应该是一个[纯函数:](https://en.wikipedia.org/wiki/Pure_function),它应该只计算 JSX。 -与[函数式组件](/learn/your-first-component#defining-a-component)类似,类组件可以从它的父组件[通过props接收信息](/learn/your-first-component#defining-a-component) 。然而,读取 props 的语法是不同的。例如,如果父组件渲染 ``,那么你可以从 [`this.props`](#props) 读取 `name` 属性,例如 `this.props.name` : +与[函数式组件](/learn/your-first-component#defining-a-component)类似,类组件可以从它的父组件[通过props接收信息](/learn/your-first-component#defining-a-component)。然而,读取 props 的语法是不同的。例如,如果父组件渲染 ``,那么你可以从 [`this.props`](#props) 读取 `name` 属性,例如 `this.props.name` : @@ -1156,7 +1156,7 @@ export default function App() { ### 向类组件添加 state {/*adding-state-to-a-class-component*/} -为了向类组件添加 [state](/learn/state-a-components-memory) ,将一个对象分配给一个名为 [`state`](#state) 的属性。要更新 state ,请调用 [`this.setState`](#setstate) 。 +为了向类组件添加 [state](/learn/state-a-components-memory),将一个对象分配给一个名为 [`state`](#state) 的属性。要更新 state,请调用 [`this.setState`](#setstate)。 @@ -1218,7 +1218,7 @@ button { display: block; margin-top: 10px; } 如果你定义了 [`componentDidMount`](#componentdidmount) 方法,当你的组件被添加到屏幕上时,React 将会调用它。当你的组件由于 props 或 state 改变而重新渲染后,React 将调用 [`componentDidUpdate`](#componentdidupdate)。当你的组件从屏幕上被移除(**卸载**)后,React 将调用 [`componentWillUnmount`](#componentwillunmount)。 -如果你实现了 `componentDidMount` ,通常需要实现所有三个生命周期以避免错误。例如,如果 `componentDidMount` 读取某些 state 或属性,你还必须实现 `componentDidUpdate` 来处理它们的更改,并实现 `componentWillUnmount` 来清理 `componentDidMount`所执行的所有操作。 +如果你实现了 `componentDidMount`,通常需要实现所有三个生命周期以避免错误。例如,如果 `componentDidMount` 读取某些 state 或属性,你还必须实现 `componentDidUpdate` 来处理它们的更改,并实现 `componentWillUnmount` 来清理 `componentDidMount`所执行的所有操作。 例如,这个 `ChatRoom` 组件使聊天连接与 props 和 state 保持同步: @@ -1336,7 +1336,7 @@ button { margin-left: 10px; } -请注意,在开发中,当 [严格模式](/reference/react/StrictMode) 开启时,React 将在调用 `componentDidMount` 后,立即调用 `componentWillUnmount` ,然后再次调用 `componentDidMount` 。这可以帮助你注意到你是否忘记实现 `componentWillUnmount` ,或者它的逻辑是否没有完全“镜像覆盖到” `componentDidMount` 的作用。 +请注意,在开发中,当 [严格模式](/reference/react/StrictMode) 开启时,React 将在调用 `componentDidMount` 后,立即调用 `componentWillUnmount`,然后再次调用 `componentDidMount`。这可以帮助你注意到你是否忘记实现 `componentWillUnmount`,或者它的逻辑是否没有完全“镜像覆盖到” `componentDidMount` 的作用。 @@ -1348,9 +1348,9 @@ button { margin-left: 10px; } ### 使用错误边界捕获渲染错误 {/*catching-rendering-errors-with-an-error-boundary*/} -默认情况下,如果你的应用程序在渲染过程中抛出错误,React 将从屏幕上删除其 UI。为了防止这种情况,你可以将 UI 的一部分包装到 **错误边界** 中。错误边界是一个特殊的组件,可让你显示一些备用 UI ,而不是例如错误消息这样崩溃的部分。 +默认情况下,如果你的应用程序在渲染过程中抛出错误,React 将从屏幕上删除其 UI。为了防止这种情况,你可以将 UI 的一部分包装到 **错误边界** 中。错误边界是一个特殊的组件,可让你显示一些备用 UI,而不是例如错误消息这样崩溃的部分。 -要实现错误边界组件,你需要提供静态 getDerivedStateFromError ,它允许你更新状态以响应错误并向用户显示错误消息。你还可以选择实现 [`componentDidCatch`](#componentdidcatch) 以添加一些额外的逻辑,例如,将错误记录到分析服务。 +要实现错误边界组件,你需要提供静态 getDerivedStateFromError,它允许你更新状态以响应错误并向用户显示错误消息。你还可以选择实现 [`componentDidCatch`](#componentdidcatch) 以添加一些额外的逻辑,例如,将错误记录到分析服务。 ```js {7-10,12-19} class ErrorBoundary extends React.Component { @@ -1444,7 +1444,7 @@ function Greeting() { } ``` -定义 `name` 属性而不是 `this.props.name` ,[使用解构语法](/learn/passing-props-to-a-component) 来直接读取它: +定义 `name` 属性而不是 `this.props.name`,[使用解构语法](/learn/passing-props-to-a-component) 来直接读取它: ```js function Greeting({ name }) { return

Hello, {name}!

; @@ -1553,7 +1553,7 @@ function Counter() { // ... ``` -最后,将所有以 `this` 开头的引用替换为你在组件中定义的变量和函数。例如,将 `this.state.age` 替换为 `age` ,将 `this.handleNameChange` 替换为 `handleNameChange` 。 +最后,将所有以 `this` 开头的引用替换为你在组件中定义的变量和函数。例如,将 `this.state.age` 替换为 `age`,将 `this.handleNameChange` 替换为 `handleNameChange`。 这是一个完全转换后的组件: @@ -1717,7 +1717,7 @@ button { margin-left: 10px; } 首先,验证你的 [`componentWillUnmount`](#componentwillunmount) 是否与 [`componentDidMount`](#componentdidmount) 执行相反的操作。在上面的示例中操作是正确的:它会断开 `componentDidMount` 设置的连接。如果缺少这样的逻辑,请先添加它。 -接下来, 验证你的 [`componentDidUpdate`](#componentdidupdate) 方法是否可以处理对 `componentDidMount` 中使用的任何 props 和 state 的更改。在上面的例子中,`componentDidMount` 调用 `setupConnection` 来读取 `this.state.serverUrl` 和 `this.props.roomId` 。这就是为什么 `componentDidUpdate` 检查 `this.state.serverUrl` 和 `this.props.roomId` 是否已更改,如果更改了则重置连接。 如果你的 `componentDidUpdate` 逻辑丢失或无法处理所有相关 props 和 state 的更改,请首先修复该问题。 +接下来, 验证你的 [`componentDidUpdate`](#componentdidupdate) 方法是否可以处理对 `componentDidMount` 中使用的任何 props 和 state 的更改。在上面的例子中,`componentDidMount` 调用 `setupConnection` 来读取 `this.state.serverUrl` 和 `this.props.roomId`。这就是为什么 `componentDidUpdate` 检查 `this.state.serverUrl` 和 `this.props.roomId` 是否已更改,如果更改了则重置连接。 如果你的 `componentDidUpdate` 逻辑丢失或无法处理所有相关 props 和 state 的更改,请首先修复该问题。 在上面的示例中,生命周期方法内的逻辑将组件连接到 React 外部的系统(聊天服务器)。要将组件连接到外部系统,[将此逻辑描述为单个效果:](/reference/react/useEffect#connecting-to-an-external-system) From 091520b66629c583df5d59993dc2fe565512f165 Mon Sep 17 00:00:00 2001 From: Tosuke <1848228664@qq.com> Date: Wed, 5 Jul 2023 15:34:17 +0800 Subject: [PATCH 03/13] chore: fix most error --- src/content/reference/react/Component.md | 308 +++++++++++------------ 1 file changed, 154 insertions(+), 154 deletions(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index ee07177b2b..dfe8c1b65f 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -4,13 +4,13 @@ title: Component -我们建议将组件定义为函数而不是类。[了解如何迁移](#alternatives) +我们建议使用函数组件,而不是类组件。[了解如何迁移](#alternatives)。 -`Component` 是被定义为 [JavaScript 类](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) 的 React 基类,类组件仍然被 React 支持,但我们不建议在新代码中使用它们。 +`Component` 是一个 [JavaScript 类](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes),被定义为react组件的基类,类组件仍然被 React 支持,但我们不建议在新代码中使用它们。 ```js class Greeting extends Component { @@ -30,7 +30,7 @@ class Greeting extends Component { ### `Component` {/*component*/} -要想将React组件定义为一个类,你需要扩展内置的 `Component` 类并定义一个 [`render` 方法](#render): +要想将 React 组件定义为一个类,你需要扩展内置的 `Component` 类并定义一个 [`render` 方法](#render): ```js import { Component } from 'react'; @@ -44,13 +44,13 @@ class Greeting extends Component { 只有 `render` 方法是必要的,其他方法是可选的。 -[查看以下的更多实例](#usage) +[查看以下的更多实例](#usage)。 --- ### `context` {/*context*/} -一个类组件的 [context](/learn/passing-data-deeply-with-context) 可以通过使用 `this.context` 来实现。 只有当你使用 [`static contextType`](#static-contexttype) (更新的)或者 [`static contextTypes`](#static-contexttypes) (已被废弃) 来特别指定你想要接受 **哪一个** context 时它才会有效。 +一个类组件的 [context](/learn/passing-data-deeply-with-context) 可以通过使用 `this.context` 来访问。只有当你使用 [`static contextType`](#static-contexttype) (更新的)或者 [`static contextTypes`](#static-contexttypes) (已被废弃)来特别指定你想要接受 **哪一个** context 时它才会有效。 类组件一次只能读取一个context。 @@ -73,9 +73,9 @@ class Button extends Component { -在类组件中读取 `this.context` 等同于在函数式组件中使用的 [`useContext`](/reference/react/useContext)。 +在类组件中读取 `this.context` 等同于在函数组件中使用的 [`useContext`](/reference/react/useContext)。 -[了解如何迁移](#migrating-a-component-with-context-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-context-from-a-class-to-a-function)。 @@ -83,7 +83,7 @@ class Button extends Component { ### `props` {/*props*/} -传递给类组件的 props 的有效形式为 `this.props`。 +`this.props` 是使用传递给类组件的 props 的使用形式。 ```js {3} class Greeting extends Component { @@ -97,9 +97,9 @@ class Greeting extends Component { -在类组件中读取 `this.props` 等同于在函数式组件中使用的 [声明式 props](/learn/passing-props-to-a-component#step-2-read-props-inside-the-child-component)。 +在类组件中读取 `this.props` 等同于在函数组件中使用的 [声明式 props](/learn/passing-props-to-a-component#step-2-read-props-inside-the-child-component)。 -[了解如何迁移](#migrating-a-simple-component-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-simple-component-from-a-class-to-a-function)。 @@ -109,7 +109,7 @@ class Greeting extends Component { -这个API将在未来React的主版本中被移除。 [使用 `createRef` 来代替](/reference/react/createRef)。 +这个 API 将在未来 React 的主版本中被移除。 [使用 `createRef` 来代替](/reference/react/createRef)。 @@ -119,7 +119,7 @@ class Greeting extends Component { ### `state` {/*state*/} -使用 `this.state` 来访问一个类组件的 state。 `state` 字段必须是一个对象。请不要直接改变 state 的值。如果你希望改变 state,使用新的 state 来调用 `setState` 函数。 +使用 `this.state` 来访问一个类组件的 state。 `state` 字段必须是一个对象。请不要直接改变 state 的值。如果你希望改变 state,那么请使用新的 state 来调用 `setState` 函数。 ```js {2-4,7-9,18} class Counter extends Component { @@ -148,9 +148,9 @@ class Counter extends Component { -在类组件中定义 `state` 等同于在函数式组件中通过调用 [`useState`](/reference/react/useState) 函数所创造的 state。 +在类组件中定义 `state` 等同于在函数组件中通过调用 [`useState`](/reference/react/useState) 函数所创造的 state。 -[了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function)。 @@ -158,7 +158,7 @@ class Counter extends Component { ### `constructor(props)` {/*constructor*/} -[constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor) 在你的类组件 **挂载**(添加到屏幕上)之前运行,一般来说,在 React 中 constructor 仅用于两个目的。它可以让你来声明 state 以及将你的类方法 [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind) 到你的类实例上。 +[constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor) 会在你的类组件 **挂载**(添加到屏幕上)之前运行。一般来说,在 React 中 constructor 仅用于两个目的。它可以让你来声明 state 以及将你的类方法 [绑定](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind) 到你的类实例上。 ```js {2-6} class Counter extends Component { @@ -173,7 +173,7 @@ class Counter extends Component { } ``` -如果你使用更新的 JavaScript 语法的话,那么很少需要使用到 constructors。相反,你可以使用现代浏览器和像 [Babel](https://babeljs.io/) 这样的工具都支持的[公有类字段语法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields)来重写上面的代码。 +如果你使用更新的 JavaScript 语法的话,那么很少需要使用到 constructors。相反,你可以使用现代浏览器和像 [Babel](https://babeljs.io/) 这样的工具都支持的 [公有类字段语法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields) 来重写上面的代码。 ```js {2,4} class Counter extends Component { @@ -184,7 +184,7 @@ class Counter extends Component { } ``` -constructor 不应该包含任何额外作用或者监听相关。 +constructor 不应该包含任何额外作用或者监听相关的代码。 #### 参数 {/*constructor-parameters*/} @@ -198,17 +198,17 @@ constructor 不应该包含任何额外作用或者监听相关。 * 不要在 constructor 中运行任何任额外作用或者监听相关的代码。相反,我们使用 [`componentDidMount`](#componentdidmount) 来解决这个问题。 -* 在 constructor 中,你需要在其他声明之前调用 `super(props)`。如果你不这样做,当 constructor 运行时 `this.props` 就会为 `undefined`, 这可能会让人迷惑并且导致错误。 +* 在 constructor 中,你需要在其他声明之前调用 `super(props)`。如果你不这样做,当 constructor 运行时 `this.props` 就会为 `undefined`, 这可能会造成困惑并且导致错误。 * Constructor 是唯一一个你能直接赋值 [`this.state`](#state) 的地方。 在其余所有方法中,你需要使用 [`this.setState()`](#setstate) 来代替。不要使用在 constructor 中使用 `setState`。 -* 当你使用 [服务端渲染](/reference/react-dom/server) 时, constructor 也将在服务端运行,紧接着是 [`render`](#render) 方法。 然而,像是 `componentDidMount` 或者 `componentWillUnmount` 这样的生命周期方法将不会在服务端运行。 +* 当你使用 [服务端渲染](/reference/react-dom/server) 时,constructor 也将在服务端运行,紧接着运行 [`render`](#render) 方法。 然而,像是 `componentDidMount` 或者 `componentWillUnmount` 这样的生命周期方法将不会在服务端运行。 * 当 [严格模式](/reference/react/StrictMode) 打开时, React 将会在开发过程中调用两次 `constructor` 然后丢弃其中的一个实例。这有助于你注意到需要从 `constructor` 中移出的意外副作用。 -在函数式组件中没有与 `constructor` 完全相同的构造函数。 要在函数式组件中声明 state 请调用 [`useState`](/reference/react/useState) 来避免重复计算 state 的初始状态。[传递一个函数给 `useState`](/reference/react/useState#avoiding-recreating-the-initial-state)。 +在函数组件中没有与 `constructor` 作用完全相同的函数。 要在函数组件中声明 state 请调用 [`useState`](/reference/react/useState) 来避免重新计算初始的 state。[传递一个函数给 `useState`](/reference/react/useState#avoiding-recreating-the-initial-state)。 @@ -216,17 +216,17 @@ constructor 不应该包含任何额外作用或者监听相关。 ### `componentDidCatch(error, info)` {/*componentdidcatch*/} -如果你定义了 `componentDidCatch`,那么当某些子组件(包括远程子组件)在渲染过程中抛出错误时React将调用它。这使得你可以在生产中将该错误记录到错误报告服务中。 +如果你定义了 `componentDidCatch`,那么当某些子组件(包括后代组件)在渲染过程中抛出错误时 React 将调用它。这使得你可以在生产中将该错误记录到错误报告服务中。 -一般来说,它与 [`static getDerivedStateFromError`](#static-getderivedstatefromerror) 一起使用,这样做允许你更新状态以响应错误并向用户显示错误消息。具有这些方法的组件称为 **错误边界**。 +一般来说,它与 [`static getDerivedStateFromError`](#static-getderivedstatefromerror) 一起使用,这样做允许你更新 state 来响应错误并向用户显示错误消息。具有这些方法的组件称为 **错误边界**。 -[查看示例](#catching-rendering-errors-with-an-error-boundary) +[查看示例](#catching-rendering-errors-with-an-error-boundary)。 #### 参数 {/*componentdidcatch-parameters*/} -* `error`: 抛出的错误。实际上,它通常会是一个 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,不过这并不能保证,因为 JavaScript 允许 [`throw`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 所有的值,包括字符串甚至是 `null`。 +* `error`: 被抛出的错误。实际上,它通常会是一个 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,不过这并不能保证,因为 JavaScript 允许 [`抛出`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 所有类型的值,包括字符串甚至是 `null`。 -* `info`: 一个包含有关错误的附加信息的对象。 它的 `componentStack` 字段包含一个堆栈跟踪,其中包含抛出的组件,以及其所有父组件的名称和源位置。在生产中,组件名称将被缩小。如果你设置了生产错误报告,则可以使用源映射来解码组件堆栈,就像处理常规 JavaScript 错误堆栈一样。 +* `info`: 一个包含有关错误的附加信息的对象。它的 `componentStack` 字段包含一个堆栈跟踪,其中包含抛出的组件,以及其所有父组件的名称和源位置。在生产中,组件名称将被简化。如果你设置了生产错误报告服务,则可以使用源映射来解码组件堆栈,就像处理常规 JavaScript 错误堆栈一样。 #### 返回值 {/*componentdidcatch-returns*/} @@ -234,13 +234,13 @@ constructor 不应该包含任何额外作用或者监听相关。 #### 说明 {/*componentdidcatch-caveats*/} -* 在以前, 经常在 `componentDidCatch` 中使用 `setState` 来更新UI以及显示回退错误消息。这已被废弃,有利于定义 [`static getDerivedStateFromError`.](#static-getderivedstatefromerror)。 +* 在以前经常会在 `componentDidCatch` 中使用 `setState` 来更新UI以及显示回退错误消息。这现在已被废弃,我们更赞同定义 [`static getDerivedStateFromError`](#static-getderivedstatefromerror)。 -* React 的生产和开发版本在 `componentDidCatch` 处理错误的方式有所不同,在开发环境下,错误将冒泡至 `window`,这意味着任何 `window.onerror` 或者 `window.addEventListener('error', callback)` 都将拦截被 `componentDidCatch` 所捕获到的错误。在生产环境下,相反,错误并不会冒泡, 这意味着任何祖先级的错误处理器都只会接收到被 `componentDidCatch` 捕获的非显式错误。 +* React 的生产和开发版本在 `componentDidCatch` 处理错误的方式有所不同,在开发环境下,错误将冒泡至 `window`,这意味着任何 `window.onerror` 或者 `window.addEventListener('error', callback)` 都将中断被 `componentDidCatch` 所捕获到的错误。而在生产环境下相反,错误并不会冒泡, 这意味着任何祖先级的错误处理器都只会接收到被 `componentDidCatch` 捕获的非显式错误。 -在函数组件中目前还没有直接等价的 `componentDidCatch`。如果你想要避免创建类组件,那么可以单独写一个像上面一样的 `ErrorBoundary` 并在整个应用中使用它。 又或者,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包,它可以完成同样的工作。 +在函数组件中没有与 `componentDidCatch` 作用完全相同的函数。如果你想要避免创建类组件,那么可以单独写一个像上面一样的 `错误边界` 并在整个应用中使用它。 又或者,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包,它可以完成同样的工作。 @@ -248,9 +248,9 @@ constructor 不应该包含任何额外作用或者监听相关。 ### `componentDidMount()` {/*componentdidmount*/} -如果你定义了 `componentDidMount` 方法, React 将会在你的组件添加上屏幕 **(mounted)** 时调用它。这是开始数据获取、设置监听或操作DOM节点的常见位置。 +如果你定义了 `componentDidMount` 方法, React 将会在你的组件添加上屏幕 **(挂载后)** 时调用它。这里是设置数据获取、设置监听或操作DOM节点的常见位置。 -如果你要执行 `componentDidMount`,你通常需要设置一些其他的生命周期函数来避免出错。例如,如果 `componentDidMount` 读取一些 state 或者 props,你还必须要设置 [`componentDidUpdate`](#componentdidupdate) 来处理它们的更改, 以及设置 [`componentWillUnmount`](#componentwillunmount) 来清理 `componentDidMount` 所产生的作用。 +如果你要执行 `componentDidMount`,你通常需要设置一些其他的生命周期函数来避免出错。例如,如果 `componentDidMount` 读取一些 state 或者 props,你还必须要设置 [`componentDidUpdate`](#componentdidupdate) 来处理它们的更新, 以及设置 [`componentWillUnmount`](#componentwillunmount) 来清理 `componentDidMount` 的效果。 ```js {6-8} class ChatRoom extends Component { @@ -280,7 +280,7 @@ class ChatRoom extends Component { } ``` -[查看更多实例](#adding-lifecycle-methods-to-a-class-component) +[查看更多示例](#adding-lifecycle-methods-to-a-class-component)。 #### 参数 {/*componentdidmount-parameters*/} @@ -292,15 +292,15 @@ class ChatRoom extends Component { #### 说明 {/*componentdidmount-caveats*/} -- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发环境中 React 会调用 `componentDidMount`,然后会立刻调用 [`componentWillUnmount`,](#componentwillunmount) 接着再次调用 `componentDidMount`。 这将帮助你注意到你是否忘记设置 `componentWillUnmount` 或者它的逻辑是否完全覆盖到 `componentDidMount` 的功能。 +- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发环境中 React 会调用 `componentDidMount`,然后会立刻调用 [`componentWillUnmount`](#componentwillunmount), 接着再次调用 `componentDidMount`。 这将帮助你注意到你是否忘记设置 `componentWillUnmount` 或者它的逻辑是否完全对应到 `componentDidMount` 的效果。 -- 虽然你可以在 `componentDidMount` 中立即调用[`setState`](#setstate),不过最好避免这样做。 这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。 这确认了在这种情况下即使 [`render`](#render) 被调用了两次, 用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下, 你应该能在[`constructor`](#constructor)中设置初始的 state。 但是,对于模态和工具提示等情况,当你需要在呈现依赖于其大小或位置的内容之前测量 DOM 节点时,它可能是必要的。 +- 虽然你可以在 `componentDidMount` 中立即调用[`setState`](#setstate),不过最好避免这样做。 因为这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。 在这种情况下即使 [`render`](#render) 被调用了两次, 用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下, 你应该能在[`constructor`](#constructor)中设置初始的 state。 但是,对于 modals 和 tooltips 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 -对于大多数的使用场景来说,在类组件中一起定义 `componentDidMount`, `componentDidUpdate`, 和 `componentWillUnmount` 等同于在函数式组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时, [`useLayoutEffect`](/reference/react/useLayoutEffect) 是一个更合适的匹配。 +对于大多数的使用场景来说,在类组件中一起定义 `componentDidMount`, `componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 -[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -310,7 +310,7 @@ class ChatRoom extends Component { 如果你定义了 `componentDidUpdate` 方法,当你的组件更新了 props 或 state 重新渲染后,React 将立即调用它。这个方法不会在首次渲染时调用。 -你可以在更新后使用它来操作 DOM。这也是进行网络请求的常见位置,只要你将当前的 props 与以前的 props 进行比较即可(例如,如果 props 没有更改,则可能不需要网络请求)。一般来说, 这个方法与[`componentDidMount`](#componentdidmount) 以及 [`componentWillUnmount`:](#componentwillunmount) 一起使用。 +你可以在更新后使用它来操作 DOM。这也是进行网络请求的常见位置,只要你将当前的 props 与以前的 props 进行比较即可(例如,如果 props 没有更改,则可能不需要网络请求)。一般来说, 这个方法与 [`componentDidMount`](#componentdidmount) 以及 [`componentWillUnmount`](#componentwillunmount) 一起使用: ```js {10-18} class ChatRoom extends Component { @@ -340,7 +340,7 @@ class ChatRoom extends Component { } ``` -[查看更多实例](#adding-lifecycle-methods-to-a-class-component) +[查看更多示例](#adding-lifecycle-methods-to-a-class-component)。 #### 参数 {/*componentdidupdate-parameters*/} @@ -349,7 +349,7 @@ class ChatRoom extends Component { * `prevState`: 更新之前的 State。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 -* `snapshot`: 如果你设置了 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),那么 `snapshot` 将包含从该方法返回的值。否则,它将是 `undefined`。 +* `snapshot`: 如果你设置了 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 方法,那么 `snapshot` 将包含从该方法返回的值。否则它将是 `undefined`。 #### 返回值 {/*componentdidupdate-returns*/} @@ -359,15 +359,15 @@ class ChatRoom extends Component { - 如果你定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并且返回 false 的话,那么 `componentDidUpdate` 将不会被调用。 -- `componentDidUpdate` 内部的逻辑通常应该包含在比较 `this.props` 与 `prevProps` 和 `this.state` 与 `prevState` 之中。 否则,就会存在创建无限循环的风险。 +- `componentDidUpdate` 内部的逻辑通常应该包含在比较 `this.props` 与 `prevProps` 和 `this.state` 与 `prevState` 之中。 否则就会存在创建无限循环的风险。 -- 虽然可以在 `componentDidUpdate` 中立即调用 [`setState`](#setstate),但最好尽可能避免这样做。它将触发一个额外的渲染,但它将在浏览器更新屏幕之前发生。 这导致了即使 [`render`](#render) 在这种情况下会被调用两次, 用户也不会看到中间状态。这种模式通常会导致性能问题,但在模态和工具提示等少数情况下,当你需要在呈现依赖于其大小或位置的内容之前测量DOM节点时,可能需要使用这种模式。 +- 虽然可以在 `componentDidUpdate` 中立即调用 [`setState`](#setstate),但最好尽可能避免这样做。它将触发一个额外的渲染,但它将在浏览器更新屏幕之前发生。 这导致了即使 [`render`](#render) 在这种情况下会被调用两次, 用户也看不到中间状态。这种模式通常会导致性能问题,对于 modals 和 tooltips 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 -对于大多数用例来说, 在类组件中一起定义 `componentDidMount`, `componentDidUpdate`, 和 `componentWillUnmount` 相当于在函数式组件中定义了 [`useEffect`](/reference/react/useEffect)。在少数情况下,代码在浏览器绘制之前运行很重要,这时 [`useLayoutEffect`](/reference/react/useLayoutEffect) 是更佳的匹配。 +对于大多数用例来说, 在类组件中一起定义 `componentDidMount`, `componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中定义了 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于[`useLayoutEffect`](/reference/react/useLayoutEffect)。 -[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 --- @@ -376,7 +376,7 @@ class ChatRoom extends Component { -此 API 已从 `componentWillMount` 重命名为 [`UNSAFE_componentWillMount`.](#unsafe_componentwillmount),旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 +此 API 已从 `componentWillMount` 重命名为 [`UNSAFE_componentWillMount`](#unsafe_componentwillmount)。旧名称已被弃用,在 React 未来主要的版本中,只有新名称才有效。 运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -388,7 +388,7 @@ class ChatRoom extends Component { -此 API 已从 `componentWillReceiveProps` 重命名为 [`UNSAFE_componentWillReceiveProps`.](#unsafe_componentwillreceiveprops),旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 +此 API 已从 `componentWillReceiveProps` 重命名为 [`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops)。旧名称已被弃用,在 React 未来主要的版本中,只有新名称才有效。 运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -400,7 +400,7 @@ class ChatRoom extends Component { -此 API 已从 `componentWillUpdate` 重命名为 [`UNSAFE_componentWillUpdate`.](#unsafe_componentwillupdate),旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 +此 API 已从 `componentWillUpdate` 重命名为 [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate)。旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -410,9 +410,9 @@ class ChatRoom extends Component { ### `componentWillUnmount()` {/*componentwillunmount*/} -如果你定义了 `componentWillUnmount` 方法,React 会在你的组件被移除屏幕之前 *(unmounted)* 调用它。这是取消数据获取或删除监听的常见位置。 +如果你定义了 `componentWillUnmount` 方法,React 会在你的组件被移除屏幕 **(卸载)** 之前调用它。这是取消数据获取或删除监听的常见位置。 -`componentWillUnmount` 内部的逻辑应该覆盖全 [`componentDidMount`.](#componentdidmount) 内部的逻辑, 例如,如果在 `componentDidMount` 中设置了一个监听,那么 `componentWillUnmount` 中应该清除掉这个监听。如果你 `componentWillUnmount` 的清理逻辑中读取了一些 props 或者 state,那么你通常还需要实现一个 [`componentDidUpdate`](#componentdidupdate) 来清理旧 props 和 state 对应的资源(例如监听)。 +`componentWillUnmount` 内部的逻辑应该完全对应 [`componentDidMount`](#componentdidmount) 内部的逻辑, 例如,如果你在 `componentDidMount` 中设置了一个监听,那么 `componentWillUnmount` 中就应该清除掉这个监听。如果你的 `componentWillUnmount` 的清理逻辑中读取了一些 props 或者 state,那么你通常还需要实现一个 [`componentDidUpdate`](#componentdidupdate) 来清理使用了旧 props 和 state 的资源(例如监听)。 ```js {20-22} class ChatRoom extends Component { @@ -442,7 +442,7 @@ class ChatRoom extends Component { } ``` -[查看更多示例](#adding-lifecycle-methods-to-a-class-component) +[查看更多示例](#adding-lifecycle-methods-to-a-class-component)。 #### 参数 {/*componentwillunmount-parameters*/} @@ -454,13 +454,13 @@ class ChatRoom extends Component { #### 说明 {/*componentwillunmount-caveats*/} -- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发中React会调用[`componentDidMount`,](#componentdidmount),然后立即调用 `componentWillUnmount`,然后再次调用 `componentDidMount`。这可以帮助你注意到你是否忘记实现 `componentWillUnmount`,或者它的逻辑是否没有完全覆盖到 `componentDidMount` 的作用。 +- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发中 React 会调用[`componentDidMount`](#componentdidmount) 然后立即调用 `componentWillUnmount`,然后再次调用 `componentDidMount`。这可以帮助你注意到你是否忘记实现 `componentWillUnmount`,或者它的逻辑是否没有完全对应到 `componentDidMount` 的效果。 -对于许多用例,在类组件中一起定义 `componentDidMount` 、 `componentDidUpdate` 和 `componentWillUnmount` 相当于在函数式组件中调用 [`useEffect`](/reference/react/useEffect)。在少数情况下,代码在浏览器绘制之前运行很重要时,[`useLayoutEffect`](/reference/react/useLayoutEffect) 是更为接近的匹配。 +对于许多用例,在类组件中一起定义 `componentDidMount` 、 `componentDidUpdate` 和 `componentWillUnmount` 相当于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于[`useLayoutEffect`](/reference/react/useLayoutEffect)。 -[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -470,7 +470,7 @@ class ChatRoom extends Component { 强制组件重新渲染。 -通常来说,这是没有必要的。如果组件的 [`render`](#render) 方法仅读取了 [`this.props`](#props) 、 [`this.state`](#state) 或 [`this.context`,]( #context) 时,当你在组件或其父组件之一内调用 [`setState`](#setstate) 时,它就将自动重新渲染。但是,如果组件的 `render` 方法直接从外部数据源读取,则必须告诉 React 在该数据源更改时更新用户界面。这就是你可以用 `forceUpdate` 做的事。 +通常来说,这是没有必要的。如果组件的 [`render`](#render) 方法仅读取了 [`this.props`](#props) 、 [`this.state`](#state) 或 [`this.context`]( #context) 时,当你在组件或其任一父组件内调用 [`setState`](#setstate) 时,它就将自动重新渲染。但是,如果组件的 `render` 方法是直接读取外部数据源时,则必须告诉 React 在该数据源更改时更新用户界面。这就是你可以用 `forceUpdate` 做的事。 尽量避免使用 `forceUpdate` 并且在 `render` 中只读取 `this.props` 和 `this.state`。 @@ -484,11 +484,11 @@ class ChatRoom extends Component { #### 说明 {/*forceupdate-caveats*/} -- 如果你调用了 `forceUpdate`, React 将重新渲染而且不会调用 [`shouldComponentUpdate`。](#shouldComponentupdate) +- 如果你调用了 `forceUpdate`, React 将重新渲染而且不会调用 [`shouldComponentUpdate`](#shouldComponentupdate)。 -读取外部数据源并强制类组件使用 `forceUpdate` 来重新渲染更改已被函数式组件中的 [`useSyncExternalStore`](/reference/react/useSyncExternalStore) 所取代。 +读取外部数据源并强制类组件使用 `forceUpdate` 来重新渲染更改已被函数组件中的 [`useSyncExternalStore`](/reference/react/useSyncExternalStore) 所取代。 @@ -498,19 +498,19 @@ class ChatRoom extends Component { -该 API 将在 React 的未来主要版本中删除。 [使用 `Context.Provider` 代替。](/reference/react/createContext#provider) +该 API 将在 React 未来主要的版本中删除。 [使用 `Context.Provider` 代替](/reference/react/createContext#provider)。 -允许你指定由该组件提供的 [legacy context](https://reactjs.org/docs/legacy-context.html) 的值。 +允许你指定由该组件提供的 [过时 context](https://reactjs.org/docs/legacy-context.html) 的值。 --- ### `getSnapshotBeforeUpdate(prevProps, prevState)` {/*getsnapshotbeforeupdate*/} -如果你实现 `getSnapshotBeforeUpdate`,React 会在 React 更新 DOM 之前立即调用它。它使你的组件能够在 DOM 发生更改之前捕获一些信息(例如滚动位置)。此生命周期方法返回的任何值都将作为参数传递给 [`componentDidUpdate`。](#componentdidupdate) +如果你实现了 `getSnapshotBeforeUpdate`,React 会在 React 更新 DOM 之前时立即调用它。它使你的组件能够在 DOM 发生更改之前捕获一些信息(例如滚动位置)。此生命周期方法返回的任何值都将作为参数传递给 [`componentDidUpdate`](#componentdidupdate)。 -例如,你可以在 UI 中像是需要在更新期间保留其滚动位置的聊天消息来使用它。 +例如,你可以在像是需要在更新期间保留其滚动位置的聊天消息的 UI 中来使用它。 ```js {7-15,17} class ScrollingList extends React.Component { @@ -557,15 +557,15 @@ class ScrollingList extends React.Component { #### 返回值 {/*getsnapshotbeforeupdate-returns*/} -你应该返回你想要的任何类型的快照值,或者 `null`。你返回的值将作为第三个参数传递给 [`componentDidUpdate`。](#componentdidupdate)。 +你应该返回你想要的任何类型的快照值,或者是 `null`。你返回的值将作为第三个参数传递给 [`componentDidUpdate`](#componentdidupdate)。 #### 说明 {/*getsnapshotbeforeupdate-caveats*/} -- 如果定义了 [`shouldComponentUpdate`](#shouldcomponentUpdate) 并返回了 `false`,则不会调用 `getSnapshotBeforeUpdate`。 +- 如果你定义了 [`shouldComponentUpdate`](#shouldcomponentUpdate) 并返回了 `false`,则 `getSnapshotBeforeUpdate` 不会被调用。 -目前,函数式组件中还没有与 `getSnapshotBeforeUpdate` 等效的API。这种用例非常罕见,但如果你有需要,那么你必须编写一个类组件。 +目前,函数组件中还没有与 `getSnapshotBeforeUpdate` 等同的方法。这种使用场景非常罕见,但如果你有需要,那么你就必须编写一个类组件。 @@ -587,9 +587,9 @@ class Greeting extends Component { } ``` -React 可能随时调用 `render`,因此你不应该假设它在特定时间运行。通常, `render` 方法应该返回一段 [JSX](/learn/writing-markup-with-jsx),但也支持一些 [其他返回类型](#render-returns)(如字符串)。为了计算返回的 JSX,`render` 方法可以读取 [`this.props`](#props)、[`this.state`](#state) 和 [`this.context`](#context)。 +React 可能随时调用 `render`,因此你不应该假设它在特定时间运行。一般来说, `render` 方法应该返回一段 [JSX](/learn/writing-markup-with-jsx),但也支持一些 [其他返回类型](#render-returns)(如字符串)。为了计算返回的 JSX,`render` 方法可以读取 [`this.props`](#props)、[`this.state`](#state) 和 [`this.context`](#context)。 -你应该将 `render` 方法编写为纯函数,这意味着如果 props、state 和 context 相同,它应该返回相同的结果。它也不应该包含额外的作用(例如设置监听)或与浏览器 API 交互。额外的作用应该发生在事件处理程序或 [`componentDidMount`.](#componentdidmount) 等方法中。 +你应该将 `render` 方法编写为纯函数,这意味着如果 props、state 和 context 相同,它应该返回相同的结果。它也不应该包含额外的作用(例如设置监听)或与浏览器 API 交互。额外的作用应该发生在事件处理程序或 [`componentDidMount`](#componentdidmount) 等方法中。 #### 参数 {/*render-parameters*/} @@ -603,16 +603,16 @@ React 可能随时调用 `render`,因此你不应该假设它在特定时间 #### 说明 {/*render-caveats*/} -- `render` 应该写成 props 、 state 和 context 的纯函数,它不应该包含额外的作用。 +- `render` 应该写成关于 props、state 和 context 的纯函数,它不应该包含额外的作用。 -- 如果定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并返回 `false`,则不会调用 `render`。 +- 如果定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并返回 `false`,则 `render` 不会被调用。 -- 当 [严格模式](/reference/react/StrictMode) 开启时,React 将在开发过程中调用 `render` 两次,然后丢弃其中一个结果。这可以帮助你注意到需要从 `render` 方法中移出的意外副作用。 - -- `render` 调用和后续的 `componentDidMount` 或 `componentDidUpdate` 调用之间没有一一对应的关系。当这样更好时,React 可能会丢弃一些 `render` 的调用结果。 +- 当 [严格模式](/reference/react/StrictMode) 开启时,React 将在开发过程中调用 `render` 两次,然后丢弃其中一个结果。这可以帮助你注意到需要从 `render` 方法中移出的意外的副作用。 +- `render` 调用和后续的 `componentDidMount` 或 `componentDidUpdate` 调用之间没有一一对应的关系。React 可能会在有益的情况下丢弃一些 `render` 的调用结果。 --- + ### `setState(nextState, callback?)` {/*setstate*/} 调用 `setState` 来更新 React 组件的 state。 @@ -641,7 +641,7 @@ class Form extends Component { } ``` -`setState` 将组件的 state 的更改加入队列。它告诉 React 该组件及其子组件需要使用新状态重新渲染。这是更新用户界面以响应交互的主要方式。 +`setState` 将组件的 state 的更改加入队列。它告诉 React 该组件及其子组件需要使用新状态重新渲染。这是更新用户界面来响应交互的主要方式。 @@ -681,7 +681,7 @@ function handleClick() { * 如果你传递一个对象作为 `nextState`,它将浅层合并到 `this.state` 中。 * 如果你传递一个函数作为 `nextState`,它将被视为 **更新函数**。它必须是个纯函数,应该以已加载的 state 和 props 作为参数,并且应该返回要浅层合并到 `this.state` 中的对象。 React 会将你的更新函数放入队列中并重新渲染你的组件。在下一次渲染期间,React 将通过应用队列中的所有更新程序来计算下一个 state。 -* **可选的** `callback`: 如果指定,React 将在提交更新后调用你提供的 `回调`。 +* **可选的** `callback`: 如果指定,React 将在提交更新后调用你提供的`回调函数`。 #### 返回值 {/*setstate-returns*/} @@ -689,15 +689,15 @@ function handleClick() { #### 说明 {/*setstate-caveats*/} -- 将 `setState` 视为 **请求**,而不是立即会更新组件的命令。当多个组件更新它们的 state 以响应事件时, React 将批量更新它们,并在这次事件结束时将它们一起重新渲染。在极少数情况下,你需要强制同步应用特定的状态更新,你可以将其包装在 [`flushSync`,](/reference/react-dom/flushSync) 中,但这可能会损害性能。 +- 将 `setState` 视为 **请求**,而不是立即会更新组件的命令。当多个组件更新它们的 state 以响应事件时, React 将批量更新它们,并在这次事件结束时将它们一起重新渲染。在极少数情况下,你需要强制同步应用特定的状态更新,你可以将其包装在 [`flushSync`](/reference/react-dom/flushSync) 中,但这可能会损害性能。 -- `setState` 不会立即更新 `this.state`。这让在调用 `setState` 之后立即读取 `setState` 成为一个潜在的陷阱。相反,请使用 [`componentDidUpdate`](#componentdidupdate) 或 setState `callback` 参数,其中任何一个都保证在更新后触发。如果需要根据前一个状态来设置状态,可以将函数传递给 `nextState`,如上所述。 +- `setState` 不会立即更新 `this.state`。这让在调用 `setState` 之后立即读取 `setState` 成为一个潜在的陷阱。相反请使用 [`componentDidUpdate`](#componentdidupdate) 或设置 setState `callback` 参数,其中任何一个都保证读取在 state 更新后触发。如果需要根据前一个 state 来设置 state,可以将函数传递给 `nextState`,如上所述。 -在类组件中调用 `setState` 等同于在函数式组件中调用 [`set` 函数](/reference/react/useState#setstate)。 +在类组件中调用 `setState` 等同于在函数组件中调用 [`set` 函数](/reference/react/useState#setstate)。 -[了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function)。 @@ -744,7 +744,7 @@ class Rectangle extends Component { #### 返回值 {/*shouldcomponentupdate-returns*/} -返回 `true` 如果你希望组件重新渲染。这是默认返回。 +返回 `true` 如果你希望组件重新渲染的话。这是也是默认执行的操作。 返回 `false` 来告诉 React 可以跳过重新渲染。 @@ -752,9 +752,9 @@ class Rectangle extends Component { - 此方法 **仅仅** 作为性能优化而存在。如果你的组件在没有它的情况下损坏,请先修复组件。 -- 可以考虑使用 [`PureComponent`](/reference/react/PureComponent) 而不是手动编写 `shouldComponentUpdate`。 `PureComponent` 浅层比较 props 和 state,并减少你跳过必要更新的机会。 +- 可以考虑使用 [`PureComponent`](/reference/react/PureComponent) 而不是手写 `shouldComponentUpdate`。 `PureComponent` 浅比较 props 和 state,这样可以减少错过必要更新的概率。 -- 我们不建议在 `shouldComponentUpdate` 中进行深度相等检查或使用 `JSON.stringify`。它使性能变得不可预测,并且依赖于每个 prop 和 state 的数据结构。在最好的情况下,你可能会冒着给应用程序引入多秒停顿的风险,而在最坏的情况下,你可能会面临使应用程序崩溃的风险。 +- 我们不建议在 `shouldComponentUpdate` 中进行深相等检查或使用 `JSON.stringify`。它使性能变得不可预测,并且依赖于每个 prop 和 state 的数据结构。在最好的情况下,你可能会面临给应用程序引入多秒停顿的风险,而在最坏的情况下,你可能会面临使应用程序崩溃的风险。 - 返回 `false` 并不会阻止子组件在 **他们的** state 发生变化时重新渲染。 @@ -762,7 +762,7 @@ class Rectangle extends Component { -使用 `shouldComponentUpdate` 优化类组件与使用 [`memo`.](/reference/react/memo) 优化函数式组件类似。函数式组件还使用 [`useMemo`.](/reference/react/useMemo) 来提供更精细的优化。 +使用 `shouldComponentUpdate` 来优化类组件与使用 [`memo`](/reference/react/memo) 来优化函数组件类似。函数组件还使用 [`useMemo`](/reference/react/useMemo) 来提供更精细的优化。 @@ -770,13 +770,12 @@ class Rectangle extends Component { ### `UNSAFE_componentWillMount()` {/*unsafe_componentwillmount*/} -如果你定义了 `UNSAFE_componentWillMount`,React 会在 [`constructor`](#constructor) 之后立即调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反,请使用一种替代方案: - -- 要初始化状态,请将 [`state`](#state) 声明为类字段或在 [`constructor`.](#constructor) 内设置 `this.state`。 +如果你定义了 `UNSAFE_componentWillMount`,React 会在 [`constructor`](#constructor) 之后立即调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反请使用其他替代方案: +- 要初始化状态,请将 [`state`](#state) 声明为类字段或在 [`constructor`](#constructor) 内设置 `this.state`。 - 如果你需要运行额外作用或设置监听,请将该逻辑移至 [`componentDidMount`](#componentdidmount)。 -[查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples) +[查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples)。 #### 参数 {/*unsafe_componentwillmount-parameters*/} @@ -788,16 +787,15 @@ class Rectangle extends Component { #### 说明 {/*unsafe_componentwillmount-caveats*/} -- 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`.](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillMount` . +- 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillMount` . -- 即使它的名字是这样的,但是如果你的应用程序使用 [`Suspense`.](/reference/react/Sus​​pense) 等现代 React 功能时,`UNSAFE_componentWillMount` 不保证组件 **将** 被安装。(例如,因为某些子组件的代码尚未加载。) React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。 这就是为什么这种方法是 **不安全** 的。依赖于挂载(例如添加监听)的代码应放入 [`componentDidMount`。](#componentdidmount) +- 即使它的名字是这样的,但是如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等现代 React 功能时,`UNSAFE_componentWillMount` 不保证组件 **将** 被安装。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载), 那么 React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。这就是为什么这种方法是 **不安全** 的。依赖于挂载(例如添加监听)的代码应放入 [`componentDidMount`](#componentdidmount)。 -- `UNSAFE_componentWillMount` 是用于所有实际目的在[服务器渲染](/reference/react-dom/server)期间运行的唯一生命周期方法,它与 [`constructor`,](#constructor) 相同,因此你应该使用 `constructor` 来代替这种类型的逻辑。 +- `UNSAFE_componentWillMount` 是运行 [服务器渲染](/reference/react-dom/server) 期间运行的唯一生命周期方法。对于所有实际用途来说,它与 [`constructor`](#constructor) 相同,因此你应该使用 `constructor` 来代替这种类型的逻辑。 -在类组件中的 `UNSAFE_componentWillMount` 内部调用 [`setState`](#setstate) 来初始化状态等同于函数式组件中用该 state 作为初始状态传递给 [`useState`]。 - +在类组件中的 `UNSAFE_componentWillMount` 内部调用 [`setState`](#setstate) 来初始化状态等同于函数组件中用该 state 作为初始 state 传递给 [`useState`]。 @@ -805,14 +803,14 @@ class Rectangle extends Component { ### `UNSAFE_componentWillReceiveProps(nextProps, nextContext)` {/*unsafe_componentwillreceiveprops*/} -如果你定义了 `UNSAFE_componentWillReceiveProps`,React 会在组件收到新的 props 时调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反,请使用以下替代方案: +如果你定义了 `UNSAFE_componentWillReceiveProps`,React 会在组件收到新的 props 时调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反请使用以下替代方案: -- 如果你需要 **运行额外作用** (例如,获取数据、运行动画或重新初始化监听)来响应 prop 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate) -- 如果你需要 **避免仅在 prop 更改时重新计算某些数据** 请使用 [memoization helper](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization) 代替。 -- 如果你需要 **在 prop 更改时`重置`某些状态**考虑制作一个组件 [fully uncontrolled](https://legacy.reactjs.org/blog/2018/06/07/you-probously-不需要派生状态。html#recommendation-fully-controlled-component) 或者 [fully uncontrolled with a key](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) instead. -- 如果你需要 **在 prop 更改时`调整`某些状态,** 检查你是否可以在渲染期间单独从 props 计算所有必要的信息。如果不能,请改用 [`static getDerivedStateFromProps`](/reference/react/Component#static-getdrivenstatefromprops)。 +- 如果你需要 **运行额外作用** (例如,获取数据、运行动画或重新初始化监听)来响应 prop 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate)。 +- 如果你需要 **避免仅在 prop 更改时重新计算某些数据** 时,请使用 [memoization helper](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization) 来代替。 +- 如果你需要 **在 prop 更改时`重置`某些状态** 时,请考虑使组件 [完全控制](https://legacy.reactjs.org/blog/2018/06/07/you-probously-不需要派生状态。html#recommendation-fully-controlled-component) 或者 [使用 key 使组件完全不受控](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) 代替。 +- 如果你需要 **在 prop 更改时`调整`某些状态,** 检查你是否可以在渲染期间单独从 props 计算所有必要的信息。如果不能,请使用 [`static getDerivedStateFromProps`](/reference/react/Component#static-getdrivenstatefromprops) 代替。 -[查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props) +[查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props)。 #### 参数 {/*unsafe_componentwillreceiveprops-parameters*/} @@ -825,9 +823,9 @@ class Rectangle extends Component { #### 说明 {/*unsafe_componentwillreceiveprops-caveats*/} -- 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`.](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillReceiveProps` +- 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillReceiveProps`。 -- 即使它的名字是这样的, 如果你的应用程序使用 [`Suspense`.](/reference/react/Sus​​pense) 等现代 React 功能,`UNSAFE_componentWillReceiveProps` 不保证组件 **将** 接收这些 Props (例如,因为某些子组件的代码尚未加载), React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。 到下一次渲染尝试时,Props 可能会有所不同。这就是为什么这种方法 **不安全**。仅为提交更新(例如重置监听)的代码应放入 [`componentDidUpdate`.](#componentdidupdate) +- 即使它的名字是这样的, 但如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等现代 React 功能,`UNSAFE_componentWillReceiveProps` 不保证组件 **将** 接收这些 Props 。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载), React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。 到下一次渲染尝试时,Props 可能会有所不同。这就是为什么这种方法 **不安全**。仅为更新(例如重置监听)的代码应放入 [`componentDidUpdate`]。(#componentdidupdate) - `UNSAFE_componentWillReceiveProps` 并不意味着组件收到了与上次 **不同的** props。你需要自己比较 `nextProps` 和 `this.props` 以检查是否发生了变化。 @@ -835,7 +833,7 @@ class Rectangle extends Component { -在类组件中的 `UNSAFE_componentWillReceiveProps` 里调用 [`setState`](#setstate) 来“调整” state 等同于在函数式组件中调用[calling the `set` function from `useState` during rendering](/reference/react/useState#storing-information-from-previous-renders)。 +在类组件中的 `UNSAFE_componentWillReceiveProps` 里调用 [`setState`](#setstate) 来“调整” state 等同于在函数组件在 [渲染期间从 `useState` 调用 `set` 函数](/reference/react/useState#storing-information-from-previous-renders)。 @@ -844,17 +842,16 @@ class Rectangle extends Component { ### `UNSAFE_componentWillUpdate(nextProps, nextState)` {/*unsafe_componentwillupdate*/} -如果你定义了`UNSAFE_componentWillUpdate`,React 会在使用新的 props 或 state 渲染之前调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反,请使用下面的替代方案: +如果你定义了 `UNSAFE_componentWillUpdate`,React 会在使用新的 props 或 state 渲染之前调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反请使用下面的替代方案: - 如果你需要运行额外作用(例如,获取数据、运行动画或重新初始化监听)来响应 prop 或 state 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate)。 - 如果需要从 DOM 中读取一些信息(例如,保存当前滚动位置)以便稍后在 [`componentDidUpdate`](#componentdidupdate) 中使用的话,那么请在 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 中读取。 -[查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples) +[查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples)。 #### 参数 {/*unsafe_componentwillupdate-parameters*/} - `nextProps`: 组件即将用来渲染的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 - - `nextState`: 组件即将渲染的下一个 state。将 `nextState` 与 [`this.state`](#state) 进行比较以确定发生了什么变化。 #### 返回值 {/*unsafe_componentwillupdate-returns*/} @@ -865,18 +862,19 @@ class Rectangle extends Component { - 如果定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并返回 `false`,则 `UNSAFE_componentWillUpdate` 将不会被调用。 -- 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`.](#getsnapshotbeforeupdate),则不会调用`UNSAFE_componentWillUpdate` +- 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillUpdate`。 -- 不支持在 `componentWillUpdate` 期间调用 [`setState`](#setstate)(或任何导致调用 `setState` 的方法,例如分派 Redux 操作)。 +- 不支持在 `componentWillUpdate` 期间调用 [`setState`](#setstate)(或任何导致调用 `setState` 的方法,例如调度 Redux 操作)。 -- 尽管它的命名是这样, `UNSAFE_componentWillUpdate` 并不能保证如果你的应用程序使用现代 React 功能(如 [`Suspense`.](/reference/react/Sus​​pense) )时,组件 **将会** 更新(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,props 和 state 可能会有所不同。 这就是为什么这种方法“不安全”。仅针对提交更新(例如重置监听)运行的代码应放入 [`componentDidUpdate`。](#componentdidupdate) +- 尽管它的命名是这样,如果你的应用程序使用如 [`Suspense`](/reference/react/Sus​​pense) 时等现代 React 功能时, `UNSAFE_componentWillUpdate` 并不能保证组件 **将会** 更新。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,props 和 state 可能会有所不同。 这就是为什么这种方法“不安全”。仅针对更新(例如重置监听)运行的代码应放入 [`componentDidUpdate`]。(#componentdidupdate) - `UNSAFE_componentWillUpdate` 并不意味着组件收到了与上次不同的 props 或状态。你需要自己将 `nextProps` 与 `this.props` 以及 `nextState` 与 `this.state` 进行比较,以检查是否发生了变化。 -- React 在挂载期间不会使用初始 props 和 state 调用 `UNSAFE_componentWillUpdate`。 +- React 在挂载期间不会使用初始的 props 和 state 调用 `UNSAFE_componentWillUpdate`。 + -函数式组件中没有与 `UNSAFE_componentWillUpdate` 直接dewng'tong的东西。 +函数组件中没有与 `UNSAFE_componentWillUpdate` 直接等同的方法。 @@ -886,11 +884,11 @@ class Rectangle extends Component { -该 API 将在 React 的未来主要版本中删除。 [使用 `static contextType` 代替。](#static-contexttype) +该 API 将在 React 未来主要的版本中删除。 [使用 `static contextType` 代替](#static-contexttype)。 -允许你指定此组件提供哪个[旧版上下文](https://reactjs.org/docs/legacy-context.html)。 +允许你指定此组件提供哪个 [旧版 context](https://reactjs.org/docs/legacy-context.html)。 --- @@ -898,17 +896,17 @@ class Rectangle extends Component { -该 API 将在 React 的未来主要版本中删除。 [使用 `static contextType` 代替。](#static-contexttype) +该 API 将在 React 的未来主要版本中删除。 [使用 `static contextType` 代替](#static-contexttype)。 -允许你指定此组件使用哪个[旧版上下文](https://reactjs.org/docs/legacy-context.html)。 +允许你指定此组件使用哪个 [旧版 context](https://reactjs.org/docs/legacy-context.html)。 --- ### `static contextType` {/*static-contexttype*/} -如果你想从类组件中读取 [`this.context`](#context-instance-field),则必须指定它需要读取哪个 context。你指定为 `static contextType` 的上下文必须是之前由 [`createContext` 创建的值。](/reference/react/createContext) +如果你想从类组件中读取 [`this.context`](#context-instance-field),则必须指定它需要读取哪个 context。你指定为 `static contextType` 的 context 必须是之前由 [`createContext` 创建的值](/reference/react/createContext)。 ```js {2} class Button extends Component { @@ -930,7 +928,7 @@ class Button extends Component { 在类组件中读取 `this.context` 等同于在函数组件中读取 [`useContext`](/reference/react/useContext)。 -[了解如何迁移](#migrating-a-component-with-context-from-a-class-to-a-function) +[了解如何迁移](#migrating-a-component-with-context-from-a-class-to-a-function)。
@@ -938,9 +936,9 @@ class Button extends Component { ### `static defaultProps` {/*static-defaultprops*/} -你可以定义 `static defaultProps` 来设置类的默认 props。它们将在props为 `undefined` 和缺少时使用,但不能用于 props 为 `null` 时。 +你可以定义 `static defaultProps` 来设置类的默认 props。它们将在 props 为 `undefined` 或者缺少时有效,但在 props 为 `null` 时无效。 -例如,以下是如何定义 `color` 属性默认为 `blue` : +例如,以下是如何定义 `color` 属性默认为 `blue`: ```js {2-4} class Button extends Component { @@ -954,7 +952,7 @@ class Button extends Component { } ``` -如果未提供 `color` props 或者为 `undefined`,它将默认设置为 `blue` : +如果 `color` props 未提供或者为 `undefined` 时,它将默认设置为 `blue`: ```js <> @@ -974,7 +972,7 @@ class Button extends Component { -在类组件中定义 `defaultProps` 类似于在函数式组件中使用[默认值](/learn/passing-props-to-a-component#specifying-a-default-value-for-a-prop)。 +在类组件中定义 `defaultProps` 类似于在函数组件中使用 [默认值](/learn/passing-props-to-a-component#specifying-a-default-value-for-a-prop)。 @@ -982,7 +980,7 @@ class Button extends Component { ### `static propTypes` {/*static-proptypes*/} -你可以定义 `static propTypes` 和 [`prop-types`](https://www.npmjs.com/package/prop-types) 库来声明组件接受的 props 类型。这些类型仅在渲染和开发过程中进行检查。 +你可以定义 `static propTypes` 和 [`prop-types`](https://www.npmjs.com/package/prop-types) 库来声明组件可接受的 props 类型。这些类型仅在渲染和开发过程中进行检查。 ```js import PropTypes from 'prop-types'; @@ -1010,27 +1008,27 @@ class Greeting extends React.Component { ### `static getDerivedStateFromError(error)` {/*static-getderivedstatefromerror*/} -如果你定义了`static getDerivedStateFromError`,当子组件(包括远程子组件)在渲染过程中抛出错误时,React 将调用它。这使你可以显示错误消息而不是清除 UI。 +如果你定义了 `static getDerivedStateFromError`,那么当子组件(包括后代组件)在渲染过程中抛出错误时,React 就会调用它。这使你可以显示错误消息而不是直接清理 UI。 -通常,它与 [`componentDidCatch`](#componentDidCatch) 一起使用,它可以让你将错误报告发送到某些分析服务。具有这些方法的组件称为 **错误边界。** +通常,它与 [`componentDidCatch`](#componentDidCatch) 一起使用,它可以让你将错误报告发送到某些分析服务。具有这些方法的组件称为 **错误边界**。 -[查看示例](#catching-rendering-errors-with-an-error-boundary) +[查看示例](#catching-rendering-errors-with-an-error-boundary)。 #### 参数 {/*static-getderivedstatefromerror-parameters*/} -* `error`: 被抛出的错误。实际上,它通常是 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,但这并不能保证,因为 JavaScript 允许 [`throw`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 任何值,包括字符串甚至 `null`。 +* `error`: 被抛出的错误。实际上,它通常是 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,但这并不能保证,因为 JavaScript 允许 [`抛出`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 任何类型的值,包括字符串甚至是 `null`。 #### 返回值 {/*static-getderivedstatefromerror-returns*/} -`static getDerivedStateFromError` 应该返回告诉组件显示错误消息的状态。 +`static getDerivedStateFromError` 应该返回告诉组件显示错误消息的 state。 #### 说明 {/*static-getderivedstatefromerror-caveats*/} -* `static getDerivedStateFromError` 应该是一个纯函数。如果你想执行额外作用(例如,调用分析服务),你还需要实现 [`componentDidCatch`.](#componentdidcatch) +* `static getDerivedStateFromError` 应该是一个纯函数。如果你想执行额外作用(例如调用分析服务),你还需要实现 [`componentDidCatch`](#componentdidcatch)。 -函数式组件中目前还没有与 `static getDerivedStateFromError` 直接等效的东西。 如果你想避免创建类组件,请像上面那样编写一个`ErrorBoundary` 组件,并在整个应用程序中使用它。或者,使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包来执行此操作。 +函数组件中目前还没有与 `static getDerivedStateFromError` 直接等同的东西。 如果你想避免创建类组件,请像上面那样编写一个 `ErrorBoundary` 组件,并在整个应用程序中使用它。或者使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包来执行此操作。 @@ -1038,9 +1036,9 @@ class Greeting extends React.Component { ### `static getDerivedStateFromProps(props, state)` {/*static-getderivedstatefromprops*/} -如果你定义了 `static getDerivedStateFromProps`,React 会在初始挂载和后续更新时调用 [`render`](#render) 之前调用它。它应该返回一个对象来更新状态,或者返回 `null` 不更新任何内容。 +如果你定义了 `static getDerivedStateFromProps`,React 会在初始挂载和后续更新调用 [`render`](#render) 的之前调用它。它应该返回一个对象来更新 state,或者返回 `null` 不更新任何内容。 -此方法适用于[少数罕见用例](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state),其中 state 取决于 props 随着时间的推移的变化。例如,当 `userID` 属性更改时,此 `Form` 组件会重置 `email` 状态: +此方法适用于 [少数罕见用例](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state),其中 state 取决于 props 随着时间的推移的变化。例如,当 `userID` 属性更改时,此 `Form` 组件会重置 `email` 状态: ```js {7-18} class Form extends Component { @@ -1066,15 +1064,16 @@ class Form extends Component { } ``` -请注意,此模式要求你将 prop 的先前值(如 `userID` )保留在状态(如 `prevUserID` )中。 +请注意,此模式要求你将 prop 的先前值(如 `userID` )保留在 state(如 `prevUserID` )中。 -派生 state 会导致代码冗长,并使你的组件难以理解。 [确保你熟悉更简单的替代方案:](https://legacy.reactjs.org/blog/2018/06/07/you-probously-dont-need-driven-state.html) +派生 state 会导致代码冗长,并使你的组件难以理解。 [确保你熟悉这些更简单的替代方案](https://legacy.reactjs.org/blog/2018/06/07/you-probously-dont-need-driven-state.html): + +- 如果你需要 **执行副作用**(例如,数据获取或动画)以响应 props 的更改,请改用 [`componentDidUpdate`](#componentdidupdate) 方法。 +- 如果你想 **仅在 prop 更改时重新计算一些数据**,[使用记忆助手代替](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization)。 +-如果你想要 **当 prop 改变时 "重置" 一些 state**,请考虑使组件 [完全控制](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) 或者 [使用 key 使组件完全不受控](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key)。 -- 如果你需要 **执行副作用** (例如,数据获取或动画)以响应 props 的更改,请改用 [`componentDidUpdate`](#componentdidupdate) 方法。 -- 如果你想 **仅在 prop 更改时重新计算一些数据,**[使用记忆助手代替。](https://legacy.reactjs.org/blog/2018/06/07/you-probously-不需要派生状态.html#what-about-memoization) --如果你想要 **当 prop 改变时 "重置" 一些 state,** 考虑制作一个组件[完全控制](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) 或者 [带key的完全非受控组件](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key)。 #### 参数 {/*static-getderivedstatefromprops-parameters*/} @@ -1084,17 +1083,17 @@ class Form extends Component { #### 返回值 {/*static-getderivedstatefromprops-returns*/} -`static getDerivedStateFromProps` 返回一个对象以更新状态,或返回 `null` 不更新任何内容。 +`static getDerivedStateFromProps` 返回一个对象来更新 state,或返回 `null` 不更新任何内容。 #### 说明 {/*static-getderivedstatefromprops-caveats*/} -- 无论原因如何,此方法都会在 **每个** 渲染时触发。这与 [`UNSAFE_componentWillReceiveProps`](#unsafe_cmoponentwillreceiveprops) 不同,后者仅在父级导致重新渲染时触发,而不是由于本地 `setState` 的结果。 +- 无论什么原因,此方法都会在 **每次** 渲染前触发。这与 [`UNSAFE_componentWillReceiveProps`](#unsafe_cmoponentwillreceiveprops) 不同,后者仅在父组件重新渲染时触发,而不是在内部调用 `setState` 时。 -- 此方法无权访问组件实例。如果你愿意,你可以通过在类定义之外提取组件 props 和 state 的纯函数,在 `static getDerivedStateFromProps` 和其他类方法之间重用一些代码。 +- 此方法无权访问组件实例。如果你愿意,您可以在 `static getDerivedStateFromProps` 和其他类方法之间重用一些代码,也就是通过提取类定义之外的组件 props 和 state 的纯函数。 -在类组件中实现 `static getDerivedStateFromProps` 等同于于在函数式组件中[在渲染期间从 useState 调用 set 函数](/reference/react/useState#storing-information-from-previous-renders)。 +在类组件中实现 `static getDerivedStateFromProps` 等同于在函数组件中 [在渲染期间从 useState 调用 set 函数](/reference/react/useState#storing-information-from-previous-renders)。 @@ -1104,7 +1103,7 @@ class Form extends Component { ### 定义类组件 {/*defining-a-class-component*/} -要将 React 组件定义为类,请扩展内置的 `Component` 类并定义 [`render` 方法:](#render) +要将 React 组件定义为类,请扩展内置的 `Component` 类并定义 [`render` 方法](#render): ```js import { Component } from 'react'; @@ -1116,9 +1115,9 @@ class Greeting extends Component { } ``` -每当 React 需要确定屏幕上显示的内容时,它就会调用你的 [`render`](#render) 方法。一般来说,你将让它返回一些 [JSX](/learn/writing-markup-with-jsx) 你的 `render` 方法应该是一个[纯函数:](https://en.wikipedia.org/wiki/Pure_function),它应该只计算 JSX。 +每当 React 需要确定屏幕上显示的内容时,它就会调用你的 [`render`](#render) 方法。一般来说,你会让它返回一些 [JSX](/learn/writing-markup-with-jsx)。你的 `render` 方法应该是一个 [纯函数](https://en.wikipedia.org/wiki/Pure_function):它应该只计算 JSX。 -与[函数式组件](/learn/your-first-component#defining-a-component)类似,类组件可以从它的父组件[通过props接收信息](/learn/your-first-component#defining-a-component)。然而,读取 props 的语法是不同的。例如,如果父组件渲染 ``,那么你可以从 [`this.props`](#props) 读取 `name` 属性,例如 `this.props.name` : +与 [函数组件](/learn/your-first-component#defining-a-component) 类似,类组件可以从它的父组件 [通过props接收信息](/learn/your-first-component#defining-a-component)。然而,读取 props 的语法是不同的。例如,如果父组件渲染 ``,那么你可以从 [`this.props`](#props) 读取 `name` 属性,例如 `this.props.name`: @@ -1148,7 +1147,7 @@ export default function App() { -我们建议将组件定义为函数而不是类。[了解如何迁移](#migrating-a-simple-component-from-a-class-to-a-function) +我们建议使用函数组件,而不是类组件。[了解如何迁移](#migrating-a-simple-component-from-a-class-to-a-function)。 @@ -1156,7 +1155,7 @@ export default function App() { ### 向类组件添加 state {/*adding-state-to-a-class-component*/} -为了向类组件添加 [state](/learn/state-a-components-memory),将一个对象分配给一个名为 [`state`](#state) 的属性。要更新 state,请调用 [`this.setState`](#setstate)。 +为了向类组件添加 [state](/learn/state-a-components-memory),请将一个对象分配给一个名为 [`state`](#state) 的属性。要更新 state 的话,请调用 [`this.setState`](#setstate)。 @@ -1206,7 +1205,7 @@ button { display: block; margin-top: 10px; } -我们建议将组件定义为函数而不是类。[了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function) +我们建议使用函数组件,而不是类组件。[了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function)。 @@ -1216,7 +1215,7 @@ button { display: block; margin-top: 10px; } 你可以在类中定义一些特殊方法。 -如果你定义了 [`componentDidMount`](#componentdidmount) 方法,当你的组件被添加到屏幕上时,React 将会调用它。当你的组件由于 props 或 state 改变而重新渲染后,React 将调用 [`componentDidUpdate`](#componentdidupdate)。当你的组件从屏幕上被移除(**卸载**)后,React 将调用 [`componentWillUnmount`](#componentwillunmount)。 +如果你定义了 [`componentDidMount`](#componentdidmount) 方法,当你的组件被添加到屏幕上(**挂载**)时,React 将会调用它。当你的组件由于 props 或 state 改变而重新渲染后,React 将调用 [`componentDidUpdate`](#componentdidupdate)。当你的组件从屏幕上被移除(**卸载**)后,React 将调用 [`componentWillUnmount`](#componentwillunmount)。 如果你实现了 `componentDidMount`,通常需要实现所有三个生命周期以避免错误。例如,如果 `componentDidMount` 读取某些 state 或属性,你还必须实现 `componentDidUpdate` 来处理它们的更改,并实现 `componentWillUnmount` 来清理 `componentDidMount`所执行的所有操作。 @@ -1336,11 +1335,11 @@ button { margin-left: 10px; } -请注意,在开发中,当 [严格模式](/reference/react/StrictMode) 开启时,React 将在调用 `componentDidMount` 后,立即调用 `componentWillUnmount`,然后再次调用 `componentDidMount`。这可以帮助你注意到你是否忘记实现 `componentWillUnmount`,或者它的逻辑是否没有完全“镜像覆盖到” `componentDidMount` 的作用。 +请注意,在开发中,当 [严格模式](/reference/react/StrictMode) 开启时,React 将在调用 `componentDidMount` 后,立即调用 `componentWillUnmount`,然后再次调用 `componentDidMount`。这可以帮助你注意到你是否忘记实现 `componentWillUnmount`,或者它的逻辑是否没有完全“对应”到 `componentDidMount` 的效果。 -我们建议将组件定义为函数而不是类。[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function) +我们建议使用函数组件,而不是类组件。[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -1350,7 +1349,7 @@ button { margin-left: 10px; } 默认情况下,如果你的应用程序在渲染过程中抛出错误,React 将从屏幕上删除其 UI。为了防止这种情况,你可以将 UI 的一部分包装到 **错误边界** 中。错误边界是一个特殊的组件,可让你显示一些备用 UI,而不是例如错误消息这样崩溃的部分。 -要实现错误边界组件,你需要提供静态 getDerivedStateFromError,它允许你更新状态以响应错误并向用户显示错误消息。你还可以选择实现 [`componentDidCatch`](#componentdidcatch) 以添加一些额外的逻辑,例如,将错误记录到分析服务。 +要实现错误边界组件,你需要提供 [`static getDerivedStateFromError`](#static-getderivedstatefromerror),它允许你更新状态以响应错误并向用户显示错误消息。你还可以选择实现 [`componentDidCatch`](#componentdidcatch) 来添加一些额外的逻辑,例如,将错误记录到分析服务。 ```js {7-10,12-19} class ErrorBoundary extends React.Component { @@ -1394,11 +1393,11 @@ class ErrorBoundary extends React.Component { 如果 `Profile` 或其子组件抛出错误,`ErrorBoundary` 将“捕获”该错误,显示带有你提供的错误消息的后备 UI,并向你的错误报告服务发送生产错误报告。 -你不需要将每个组件包装到单独的错误边界中。当你考虑[错误边界的布置](https://aweary.dev/fault-tolerance-react/)时,请考虑在哪里显示错误消息才有意义。例如,在消息传递应用程序中,在对话列表周围放置错误边界是有意义的。在每条单独的消息周围放置一个也是有意义的。然而,在每个头像周围设置边界是没有意义的。 +你不需要将每个组件包装到单独的错误边界中。当你考虑 [错误边界的布置](https://aweary.dev/fault-tolerance-react/) 时,请考虑在哪里显示错误消息才有意义。例如,在消息传递应用程序中,在对话列表周围放置错误边界是有意义的。在每条单独的消息周围放置一个也是有意义的。然而,在每个头像周围设置边界是没有意义的。 -目前还没有办法将错误边界编写为函数组件。但是,你不必自己编写错误边界类。例如,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 代替。 +目前还没有办法将错误边界编写为函数组件。但是你不必自己编写错误边界类。例如,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包来代替。 @@ -1408,7 +1407,7 @@ class ErrorBoundary extends React.Component { ### 将简单的类组件迁移为函数式 {/*migrating-a-simple-component-from-a-class-to-a-function*/} -一般来说,你[将组件定义为函数](/learn/your-first-component#defining-a-component)。 +一般来说,你会把 [组件定义为函数](/learn/your-first-component#defining-a-component)。 例如,假设你要将 `Greeting` 从类组件转换为函数: @@ -1436,7 +1435,7 @@ export default function App() { -定义一个名为 `Greeting` 的函数。你将移动 `render` 函数的主体到这里。 +定义一个名为 `Greeting` 的函数。将 `render` 函数的主体移动到这里。 ```js function Greeting() { @@ -1445,6 +1444,7 @@ function Greeting() { ``` 定义 `name` 属性而不是 `this.props.name`,[使用解构语法](/learn/passing-props-to-a-component) 来直接读取它: + ```js function Greeting({ name }) { return

Hello, {name}!

; @@ -1477,7 +1477,7 @@ export default function App() { ### 将具有状态的类组件迁移到函数 {/*migrating-a-component-with-state-from-a-class-to-a-function*/} -Suppose you're converting this `Counter` class component to a function: +假设你要将这个 `Counter` 从类组件转换为函数: @@ -1525,7 +1525,7 @@ button { display: block; margin-top: 10px; } -首先用必要的 [state variables](/reference/react/useState#adding-state-to-a-component) 来创建一个函数。 +首先用必要的 [state 变量](/reference/react/useState#adding-state-to-a-component) 来创建一个函数。 ```js {4-5} import { useState } from 'react'; @@ -1719,7 +1719,7 @@ button { margin-left: 10px; } 接下来, 验证你的 [`componentDidUpdate`](#componentdidupdate) 方法是否可以处理对 `componentDidMount` 中使用的任何 props 和 state 的更改。在上面的例子中,`componentDidMount` 调用 `setupConnection` 来读取 `this.state.serverUrl` 和 `this.props.roomId`。这就是为什么 `componentDidUpdate` 检查 `this.state.serverUrl` 和 `this.props.roomId` 是否已更改,如果更改了则重置连接。 如果你的 `componentDidUpdate` 逻辑丢失或无法处理所有相关 props 和 state 的更改,请首先修复该问题。 -在上面的示例中,生命周期方法内的逻辑将组件连接到 React 外部的系统(聊天服务器)。要将组件连接到外部系统,[将此逻辑描述为单个效果:](/reference/react/useEffect#connecting-to-an-external-system) +在上面的示例中,生命周期方法内的逻辑将组件连接到 React 外部的系统(聊天服务器)。要将组件连接到外部系统,[将此逻辑描述为单个效果](/reference/react/useEffect#connecting-to-an-external-system): ```js {6-12} import { useState, useEffect } from 'react'; @@ -1739,7 +1739,7 @@ function ChatRoom({ roomId }) { } ``` -这个 [`useEffect`](/reference/react/useEffect) 调用相当于上面生命周期方法中的逻辑。如果你的生命周期方法做了多个互不相关的事,[将它们分成多个独立的效果](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things)。这是一个你可以使用的完整示例: +这个 [`useEffect`](/reference/react/useEffect) 的调用就相当于实现了上面所有生命周期方法中的逻辑。如果你的生命周期方法做了多个互不相关的事,[将它们分成多个独立的效果](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things)。这是一个你可以使用的完整示例: @@ -1826,7 +1826,7 @@ button { margin-left: 10px; } -如果你的组件不与任何外部系统同步,[你可能不需要 effect ](/learn/you-might-not-need-an-effect) +如果你的组件不与任何外部系统同步,[你可能不需要 effect ](/learn/you-might-not-need-an-effect)。 @@ -1834,7 +1834,7 @@ button { margin-left: 10px; } ### 将具有 context 的组件从类迁移到函数 {/*migrating-a-component-with-context-from-a-class-to-a-function*/} -在这个例子中,`Panel` 和 `Button` 类组件从 [`this.context`:](#context) 读取 [context](/learn/passing-data-deeply-with-context)。 +在这个例子中,`Panel` 和 `Button` 类组件从 [`this.context`](#context) 读取 [context](/learn/passing-data-deeply-with-context): @@ -1928,7 +1928,7 @@ export default function MyApp() { -当你将它们转换为函数组件时,将 `this.context` 替换为 [`useContext`](/reference/react/useContext) 调用: +当你将它们转换为函数组件时,将 `this.context` 用调用[`useContext`](/reference/react/useContext)来替换: From 36d04ccd7f18b2970d824dc4e127dc282bc8904d Mon Sep 17 00:00:00 2001 From: Tosuke <1848228664@qq.com> Date: Wed, 5 Jul 2023 15:44:11 +0800 Subject: [PATCH 04/13] chore: update branch --- src/content/reference/react/Component.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index dfe8c1b65f..b5d9a711a1 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -10,7 +10,7 @@ title: Component -`Component` 是一个 [JavaScript 类](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes),被定义为react组件的基类,类组件仍然被 React 支持,但我们不建议在新代码中使用它们。 +`Component` 是一个 [JavaScript 类](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes),是被定义为react组件的基类,类组件仍然被 React 支持,但我们不建议在新代码中使用它们。 ```js class Greeting extends Component { From 5b233b53707551b5ab6f751d7a6d0b9abe34928b Mon Sep 17 00:00:00 2001 From: Xavi Lee Date: Thu, 6 Jul 2023 14:25:31 +0800 Subject: [PATCH 05/13] Update src/content/reference/react/Component.md Co-authored-by: Yucohny <79147654+Yucohny@users.noreply.github.com> --- src/content/reference/react/Component.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index b5d9a711a1..d1b57e849c 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -298,7 +298,7 @@ class ChatRoom extends Component { -对于大多数的使用场景来说,在类组件中一起定义 `componentDidMount`, `componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 +对于大多数的使用场景来说,在类组件中一起定义 `componentDidMount`,`componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 From 084f41ef12d38923e847b41665849b1e8d812c6f Mon Sep 17 00:00:00 2001 From: Xavi Lee Date: Thu, 6 Jul 2023 14:26:27 +0800 Subject: [PATCH 06/13] Update src/content/reference/react/Component.md Co-authored-by: Yucohny <79147654+Yucohny@users.noreply.github.com> --- src/content/reference/react/Component.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index d1b57e849c..f34059d08d 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -294,7 +294,7 @@ class ChatRoom extends Component { - 当 [严格模式](/reference/react/StrictMode) 开启时,在开发环境中 React 会调用 `componentDidMount`,然后会立刻调用 [`componentWillUnmount`](#componentwillunmount), 接着再次调用 `componentDidMount`。 这将帮助你注意到你是否忘记设置 `componentWillUnmount` 或者它的逻辑是否完全对应到 `componentDidMount` 的效果。 -- 虽然你可以在 `componentDidMount` 中立即调用[`setState`](#setstate),不过最好避免这样做。 因为这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。 在这种情况下即使 [`render`](#render) 被调用了两次, 用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下, 你应该能在[`constructor`](#constructor)中设置初始的 state。 但是,对于 modals 和 tooltips 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 +- 虽然你可以在 `componentDidMount` 中立即调用[`setState`](#setstate),不过最好避免这样做。 因为这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。 在这种情况下即使 [`render`](#render) 被调用了两次, 用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下, 你应该能在 [`constructor`](#constructor) 中设置初始的 state。 但是,对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 From d51306a8d0b2050903bde21869e265518d8a6e07 Mon Sep 17 00:00:00 2001 From: Tosuke <1848228664@qq.com> Date: Sat, 8 Jul 2023 00:28:45 +0800 Subject: [PATCH 07/13] chore: fix most error --- src/content/reference/react/Component.md | 92 ++++++++++++------------ 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index b5d9a711a1..27948a4d52 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -294,11 +294,11 @@ class ChatRoom extends Component { - 当 [严格模式](/reference/react/StrictMode) 开启时,在开发环境中 React 会调用 `componentDidMount`,然后会立刻调用 [`componentWillUnmount`](#componentwillunmount), 接着再次调用 `componentDidMount`。 这将帮助你注意到你是否忘记设置 `componentWillUnmount` 或者它的逻辑是否完全对应到 `componentDidMount` 的效果。 -- 虽然你可以在 `componentDidMount` 中立即调用[`setState`](#setstate),不过最好避免这样做。 因为这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。 在这种情况下即使 [`render`](#render) 被调用了两次, 用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下, 你应该能在[`constructor`](#constructor)中设置初始的 state。 但是,对于 modals 和 tooltips 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 +- 虽然你可以在 `componentDidMount` 中立即调用 [`setState`](#setstate),不过最好避免这样做。 因为这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。 在这种情况下即使 [`render`](#render) 被调用了两次,用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下, 你应该能在 [`constructor`](#constructor) 中设置初始的 state。 但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 -对于大多数的使用场景来说,在类组件中一起定义 `componentDidMount`, `componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 +对于大多数的使用场景来说,在类组件中一起定义 `componentDidMount`,`componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -310,7 +310,7 @@ class ChatRoom extends Component { 如果你定义了 `componentDidUpdate` 方法,当你的组件更新了 props 或 state 重新渲染后,React 将立即调用它。这个方法不会在首次渲染时调用。 -你可以在更新后使用它来操作 DOM。这也是进行网络请求的常见位置,只要你将当前的 props 与以前的 props 进行比较即可(例如,如果 props 没有更改,则可能不需要网络请求)。一般来说, 这个方法与 [`componentDidMount`](#componentdidmount) 以及 [`componentWillUnmount`](#componentwillunmount) 一起使用: +你可以在更新后使用它来操作 DOM。这也是进行网络请求的常见位置,只要你将当前的 props 与以前的 props 进行比较即可(例如,如果 props 没有更改,则可能不需要网络请求)。一般来说,这个方法与 [`componentDidMount`](#componentdidmount) 以及 [`componentWillUnmount`](#componentwillunmount) 一起使用: ```js {10-18} class ChatRoom extends Component { @@ -345,9 +345,9 @@ class ChatRoom extends Component { #### 参数 {/*componentdidupdate-parameters*/} -* `prevProps`: 更新之前的 Props。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`: 更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: 更新之前的 State。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`: 更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 * `snapshot`: 如果你设置了 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 方法,那么 `snapshot` 将包含从该方法返回的值。否则它将是 `undefined`。 @@ -359,13 +359,13 @@ class ChatRoom extends Component { - 如果你定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并且返回 false 的话,那么 `componentDidUpdate` 将不会被调用。 -- `componentDidUpdate` 内部的逻辑通常应该包含在比较 `this.props` 与 `prevProps` 和 `this.state` 与 `prevState` 之中。 否则就会存在创建无限循环的风险。 +- `componentDidUpdate` 内部的逻辑通常应该包含在比较 `this.props` 与 `prevProps` 以及 `this.state` 与 `prevState` 之中。否则就会存在创建无限循环的风险。 -- 虽然可以在 `componentDidUpdate` 中立即调用 [`setState`](#setstate),但最好尽可能避免这样做。它将触发一个额外的渲染,但它将在浏览器更新屏幕之前发生。 这导致了即使 [`render`](#render) 在这种情况下会被调用两次, 用户也看不到中间状态。这种模式通常会导致性能问题,对于 modals 和 tooltips 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 +- 虽然可以在 `componentDidUpdate` 中立即调用 [`setState`](#setstate),但最好尽可能避免这样做。它将触发一个额外的渲染,但它将在浏览器更新屏幕之前发生。这导致了即使 [`render`](#render) 在这种情况下会被调用两次,用户也看不到中间状态。这种模式通常会导致性能问题,但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 -对于大多数用例来说, 在类组件中一起定义 `componentDidMount`, `componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中定义了 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于[`useLayoutEffect`](/reference/react/useLayoutEffect)。 +对于大多数用例来说, 在类组件中一起定义 `componentDidMount`,`componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中定义 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于[`useLayoutEffect`](/reference/react/useLayoutEffect)。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -412,7 +412,7 @@ class ChatRoom extends Component { 如果你定义了 `componentWillUnmount` 方法,React 会在你的组件被移除屏幕 **(卸载)** 之前调用它。这是取消数据获取或删除监听的常见位置。 -`componentWillUnmount` 内部的逻辑应该完全对应 [`componentDidMount`](#componentdidmount) 内部的逻辑, 例如,如果你在 `componentDidMount` 中设置了一个监听,那么 `componentWillUnmount` 中就应该清除掉这个监听。如果你的 `componentWillUnmount` 的清理逻辑中读取了一些 props 或者 state,那么你通常还需要实现一个 [`componentDidUpdate`](#componentdidupdate) 来清理使用了旧 props 和 state 的资源(例如监听)。 +`componentWillUnmount` 内部的逻辑应该完全对应 [`componentDidMount`](#componentdidmount) 内部的逻辑,例如,如果你在 `componentDidMount` 中设置了一个监听,那么 `componentWillUnmount` 中就应该清除掉这个监听。如果你的 `componentWillUnmount` 的清理逻辑中读取了一些 props 或者 state,那么你通常还需要实现一个 [`componentDidUpdate`](#componentdidupdate) 来清理使用了旧 props 和 state 的资源(例如监听)。 ```js {20-22} class ChatRoom extends Component { @@ -454,11 +454,11 @@ class ChatRoom extends Component { #### 说明 {/*componentwillunmount-caveats*/} -- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发中 React 会调用[`componentDidMount`](#componentdidmount) 然后立即调用 `componentWillUnmount`,然后再次调用 `componentDidMount`。这可以帮助你注意到你是否忘记实现 `componentWillUnmount`,或者它的逻辑是否没有完全对应到 `componentDidMount` 的效果。 +- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发中 React 会调用 [`componentDidMount`](#componentdidmount) 然后立即调用 `componentWillUnmount`,接着再次调用 `componentDidMount`。这可以帮助你注意到你是否忘记实现 `componentWillUnmount`,或者它的逻辑是否没有完全对应到 `componentDidMount` 的效果。 -对于许多用例,在类组件中一起定义 `componentDidMount` 、 `componentDidUpdate` 和 `componentWillUnmount` 相当于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于[`useLayoutEffect`](/reference/react/useLayoutEffect)。 +对于许多用例,在类组件中一起定义 `componentDidMount`、`componentDidUpdate` 和 `componentWillUnmount` 相当于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -470,13 +470,13 @@ class ChatRoom extends Component { 强制组件重新渲染。 -通常来说,这是没有必要的。如果组件的 [`render`](#render) 方法仅读取了 [`this.props`](#props) 、 [`this.state`](#state) 或 [`this.context`]( #context) 时,当你在组件或其任一父组件内调用 [`setState`](#setstate) 时,它就将自动重新渲染。但是,如果组件的 `render` 方法是直接读取外部数据源时,则必须告诉 React 在该数据源更改时更新用户界面。这就是你可以用 `forceUpdate` 做的事。 +通常来说,这是没必要的。如果组件的 [`render`](#render) 方法仅读取了 [`this.props`](#props)、[`this.state`](#state) 或 [`this.context`]( #context) 时,当你在组件或其任一父组件内调用 [`setState`](#setstate) 时,它就将自动重新渲染。但是,如果组件的 `render` 方法是直接读取外部数据源时,则必须告诉 React 在该数据源更改时更新用户界面。这就是你可以用 `forceUpdate` 做的事。 尽量避免使用 `forceUpdate` 并且在 `render` 中只读取 `this.props` 和 `this.state`。 #### 参数 {/*forceupdate-parameters*/} -* **optional** `callback` 如果有指定,React 将在提交更新后调用你提供的 `callback`。 +* **可选的** 如果指定了 `callback`,React 将在提交更新后调用你提供的 `callback`。 #### 返回值 {/*forceupdate-returns*/} @@ -502,7 +502,7 @@ class ChatRoom extends Component {
-允许你指定由该组件提供的 [过时 context](https://reactjs.org/docs/legacy-context.html) 的值。 +允许你指定由该组件提供的 [过时的 context](https://reactjs.org/docs/legacy-context.html) 的值。 --- @@ -547,13 +547,13 @@ class ScrollingList extends React.Component { } ``` -在上面的示例中,直接在 `getSnapshotBeforeUpdate` 中读取 `scrollHeight` 属性非常重要。在 [`render`](#render) 、 [`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops) 或 [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate) 中读取它是不安全的,因为在这些方法被调用和 React 更新 DOM 之间存在潜在的时间间隔。 +在上面的示例中,直接在 `getSnapshotBeforeUpdate` 中读取 `scrollHeight` 属性非常重要。在 [`render`](#render)、[`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops) 或 [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate) 中读取它是不安全的,因为在这些方法被调用和 React 更新 DOM 之间存在潜在的时间间隔。 #### 参数 {/*getsnapshotbeforeupdate-parameters*/} -* `prevProps`: 更新之前的 Props。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`: 更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: 更新之前的 State。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`: 更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 #### 返回值 {/*getsnapshotbeforeupdate-returns*/} @@ -593,13 +593,13 @@ React 可能随时调用 `render`,因此你不应该假设它在特定时间 #### 参数 {/*render-parameters*/} -* `prevProps`: 更新之前的 Props。 `prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`: 更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: 更新之前的 State。 `prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`: 更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 #### 返回值 {/*render-returns*/} -`render` 可以返回任何有效的 React 节点。这包括 React 元素,例如 `
`、字符串、数字、 [portals](/reference/react-dom/createPortal) 、空节点(`null`、`undefined`、`true` 和 `false` )和 React 节点数组。 +`render` 可以返回任何有效的 React 节点。这包括 React 元素,例如 `
`、字符串、数字、[portals](/reference/react-dom/createPortal)、空节点(`null`、`undefined`、`true` 和 `false`)和 React 节点数组。 #### 说明 {/*render-caveats*/} @@ -673,15 +673,15 @@ function handleClick() { } ``` -你不必这样做,但如果你想在同一事件期间多次更新状态,这会很方便。 +你不必这样做,但如果你想在同一事件期间多次更新状态,这样就会很方便。 #### 参数 {/*setstate-parameters*/} * `nextState`: 一个对象或者函数。 * 如果你传递一个对象作为 `nextState`,它将浅层合并到 `this.state` 中。 - * 如果你传递一个函数作为 `nextState`,它将被视为 **更新函数**。它必须是个纯函数,应该以已加载的 state 和 props 作为参数,并且应该返回要浅层合并到 `this.state` 中的对象。 React 会将你的更新函数放入队列中并重新渲染你的组件。在下一次渲染期间,React 将通过应用队列中的所有更新程序来计算下一个 state。 + * 如果你传递一个函数作为 `nextState`,它将被视为 **更新函数**。它必须是个纯函数,应该以已加载的 state 和 props 作为参数,并且应该返回要浅层合并到 `this.state` 中的对象。React 会将你的更新函数放入队列中并重新渲染你的组件。在下一次渲染期间,React 将通过应用队列中的所有更新程序来计算下一个 state。 -* **可选的** `callback`: 如果指定,React 将在提交更新后调用你提供的`回调函数`。 +* **可选的** `callback`: 如果你指定,React 将在提交更新后调用你提供的`回调函数`。 #### 返回值 {/*setstate-returns*/} @@ -689,7 +689,7 @@ function handleClick() { #### 说明 {/*setstate-caveats*/} -- 将 `setState` 视为 **请求**,而不是立即会更新组件的命令。当多个组件更新它们的 state 以响应事件时, React 将批量更新它们,并在这次事件结束时将它们一起重新渲染。在极少数情况下,你需要强制同步应用特定的状态更新,你可以将其包装在 [`flushSync`](/reference/react-dom/flushSync) 中,但这可能会损害性能。 +- 将 `setState` 视为 **请求**,而不是立即会更新组件的命令。当多个组件更新它们的 state 以响应事件时,React 将批量更新它们,并在这次事件结束时将它们一并重新渲染。在极少数情况下,你需要强制同步应用特定的状态更新,你可以将其包装在 [`flushSync`](/reference/react-dom/flushSync) 中,但这可能会损害性能。 - `setState` 不会立即更新 `this.state`。这让在调用 `setState` 之后立即读取 `setState` 成为一个潜在的陷阱。相反请使用 [`componentDidUpdate`](#componentdidupdate) 或设置 setState `callback` 参数,其中任何一个都保证读取在 state 更新后触发。如果需要根据前一个 state 来设置 state,可以将函数传递给 `nextState`,如上所述。 @@ -707,7 +707,7 @@ function handleClick() { 如果你定义了 `shouldComponentUpdate`,React 将调用它来确定是否可以跳过重新渲染。 -如果你确信你想手动编写它,你可以将`this.props`与`nextProps`进行比较,将`this.state`与`nextState`进行比较,并返回`false`来告诉React可以跳过更新。 +如果你确定你想手动编写它,你可以将 `this.props` 与 `nextProps` 以及 `this.state` 与 `nextState` 进行比较,并返回 `false` 来告诉 React 可以跳过更新。 ```js {6-18} class Rectangle extends Component { @@ -740,11 +740,11 @@ class Rectangle extends Component { - `nextProps`: 组件即将用来渲染的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 - `nextState`: 组件即将渲染的下一个 state。将 `nextState` 与 [`this.state`](#props) 进行比较以确定发生了什么变化。 -- `nextContext`: 组件将要渲染的下一个上下文。将 `nextContext` 与 [`this.context`](#context) 进行比较以确定发生了什么变化。仅当你指定了 [`static contextType`](#static-contexttype)(更新的)或 [`static contextTypes`](#static-contexttypes)(旧版)时才可用。 +- `nextContext`: 组件将要渲染的下一个 context。将 `nextContext` 与 [`this.context`](#context) 进行比较以确定发生了什么变化。仅当你指定了 [`static contextType`](#static-contexttype)(更新的)或 [`static contextTypes`](#static-contexttypes)(旧版)时才可用。 #### 返回值 {/*shouldcomponentupdate-returns*/} -返回 `true` 如果你希望组件重新渲染的话。这是也是默认执行的操作。 +如果你希望组件重新渲染的话,返回 `true`。这是也是默认执行的操作。 返回 `false` 来告诉 React 可以跳过重新渲染。 @@ -752,13 +752,13 @@ class Rectangle extends Component { - 此方法 **仅仅** 作为性能优化而存在。如果你的组件在没有它的情况下损坏,请先修复组件。 -- 可以考虑使用 [`PureComponent`](/reference/react/PureComponent) 而不是手写 `shouldComponentUpdate`。 `PureComponent` 浅比较 props 和 state,这样可以减少错过必要更新的概率。 +- 可以考虑使用 [`PureComponent`](/reference/react/PureComponent) 而不是手写 `shouldComponentUpdate`。`PureComponent` 浅比较 props 和 state,这样可以减少错过必要更新的概率。 -- 我们不建议在 `shouldComponentUpdate` 中进行深相等检查或使用 `JSON.stringify`。它使性能变得不可预测,并且依赖于每个 prop 和 state 的数据结构。在最好的情况下,你可能会面临给应用程序引入多秒停顿的风险,而在最坏的情况下,你可能会面临使应用程序崩溃的风险。 +- 我们不建议在 `shouldComponentUpdate` 中进行深度相等检查或使用 `JSON.stringify`。因为它使性能变得不可预测并且它与每个 prop 和 state 的数据结构有关。在最好的情况下,你可能会面临给应用程序引入多秒停顿的风险,而在最坏的情况下,你可能会面临使应用程序崩溃的风险。 - 返回 `false` 并不会阻止子组件在 **他们的** state 发生变化时重新渲染。 -- 返回 `false` 并不能 **确保** 组件不会重新渲染。 React 将使用返回值作为提示,但如果出于其他有意义原因,它仍然可能选择重新渲染你的组件。 +- 返回 `false` 并不能 **确保** 组件不会重新渲染。React 将使用返回值作为提示,但如果出于其他有意义原因,它仍然可能选择重新渲染你的组件。 @@ -787,9 +787,9 @@ class Rectangle extends Component { #### 说明 {/*unsafe_componentwillmount-caveats*/} -- 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillMount` . +- 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillMount`。 -- 即使它的名字是这样的,但是如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等现代 React 功能时,`UNSAFE_componentWillMount` 不保证组件 **将** 被安装。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载), 那么 React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。这就是为什么这种方法是 **不安全** 的。依赖于挂载(例如添加监听)的代码应放入 [`componentDidMount`](#componentdidmount)。 +- 即使它的名字是这样的,但是如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等现代 React 功能时,`UNSAFE_componentWillMount` 不保证组件 **将** 被挂载。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),那么 React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。这就是为什么这种方法是 **不安全** 的。依赖于挂载(例如添加监听)的代码应放入 [`componentDidMount`](#componentdidmount)。 - `UNSAFE_componentWillMount` 是运行 [服务器渲染](/reference/react-dom/server) 期间运行的唯一生命周期方法。对于所有实际用途来说,它与 [`constructor`](#constructor) 相同,因此你应该使用 `constructor` 来代替这种类型的逻辑。 @@ -805,7 +805,7 @@ class Rectangle extends Component { 如果你定义了 `UNSAFE_componentWillReceiveProps`,React 会在组件收到新的 props 时调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反请使用以下替代方案: -- 如果你需要 **运行额外作用** (例如,获取数据、运行动画或重新初始化监听)来响应 prop 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate)。 +- 如果你需要 **运行额外作用**(例如,获取数据、运行动画或重新初始化监听)来响应 prop 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate)。 - 如果你需要 **避免仅在 prop 更改时重新计算某些数据** 时,请使用 [memoization helper](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization) 来代替。 - 如果你需要 **在 prop 更改时`重置`某些状态** 时,请考虑使组件 [完全控制](https://legacy.reactjs.org/blog/2018/06/07/you-probously-不需要派生状态。html#recommendation-fully-controlled-component) 或者 [使用 key 使组件完全不受控](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) 代替。 - 如果你需要 **在 prop 更改时`调整`某些状态,** 检查你是否可以在渲染期间单独从 props 计算所有必要的信息。如果不能,请使用 [`static getDerivedStateFromProps`](/reference/react/Component#static-getdrivenstatefromprops) 代替。 @@ -825,7 +825,7 @@ class Rectangle extends Component { - 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillReceiveProps`。 -- 即使它的名字是这样的, 但如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等现代 React 功能,`UNSAFE_componentWillReceiveProps` 不保证组件 **将** 接收这些 Props 。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载), React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。 到下一次渲染尝试时,Props 可能会有所不同。这就是为什么这种方法 **不安全**。仅为更新(例如重置监听)的代码应放入 [`componentDidUpdate`]。(#componentdidupdate) +- 即使它的名字是这样的, 但如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等现代 React 功能时,`UNSAFE_componentWillReceiveProps` 不保证组件 **将会** 接收这些 Props。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,Props 可能会有所不同。这就是为什么这种方法 **不安全**。仅为更新(例如重置监听)的代码应放入 [`componentDidUpdate`](#componentdidupdate)。 - `UNSAFE_componentWillReceiveProps` 并不意味着组件收到了与上次 **不同的** props。你需要自己比较 `nextProps` 和 `this.props` 以检查是否发生了变化。 @@ -866,9 +866,9 @@ class Rectangle extends Component { - 不支持在 `componentWillUpdate` 期间调用 [`setState`](#setstate)(或任何导致调用 `setState` 的方法,例如调度 Redux 操作)。 -- 尽管它的命名是这样,如果你的应用程序使用如 [`Suspense`](/reference/react/Sus​​pense) 时等现代 React 功能时, `UNSAFE_componentWillUpdate` 并不能保证组件 **将会** 更新。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,props 和 state 可能会有所不同。 这就是为什么这种方法“不安全”。仅针对更新(例如重置监听)运行的代码应放入 [`componentDidUpdate`]。(#componentdidupdate) +- 尽管它的命名是这样,但如果你的应用程序使用如 [`Suspense`](/reference/react/Sus​​pense) 时等现代 React 功能时,`UNSAFE_componentWillUpdate` 并不能保证组件 **将会** 更新。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,props 和 state 可能会有所不同。 这就是为什么这种方法“不安全”。仅针对更新(例如重置监听)运行的代码应放入 [`componentDidUpdate`](#componentdidupdate)。 -- `UNSAFE_componentWillUpdate` 并不意味着组件收到了与上次不同的 props 或状态。你需要自己将 `nextProps` 与 `this.props` 以及 `nextState` 与 `this.state` 进行比较,以检查是否发生了变化。 +- `UNSAFE_componentWillUpdate` 并不意味着组件收到了与上次不同的 props 或 state。你需要自己将 `nextProps` 与 `this.props` 以及 `nextState` 与 `this.state` 进行比较,以检查是否发生了变化。 - React 在挂载期间不会使用初始的 props 和 state 调用 `UNSAFE_componentWillUpdate`。 @@ -884,7 +884,7 @@ class Rectangle extends Component { -该 API 将在 React 未来主要的版本中删除。 [使用 `static contextType` 代替](#static-contexttype)。 +该 API 将在 React 未来主要的版本中删除。[使用 `static contextType` 代替](#static-contexttype)。 @@ -896,7 +896,7 @@ class Rectangle extends Component { -该 API 将在 React 的未来主要版本中删除。 [使用 `static contextType` 代替](#static-contexttype)。 +该 API 将在 React 的未来主要版本中删除。[使用 `static contextType` 代替](#static-contexttype)。 @@ -1028,7 +1028,7 @@ class Greeting extends React.Component { -函数组件中目前还没有与 `static getDerivedStateFromError` 直接等同的东西。 如果你想避免创建类组件,请像上面那样编写一个 `ErrorBoundary` 组件,并在整个应用程序中使用它。或者使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包来执行此操作。 +函数组件中目前还没有与 `static getDerivedStateFromError` 直接等同的东西。如果你想避免创建类组件,请像上面那样编写一个 `ErrorBoundary` 组件,并在整个应用程序中使用它。或者使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包来执行此操作。 @@ -1050,7 +1050,7 @@ class Form extends Component { static getDerivedStateFromProps(props, state) { // 每当当前用户发生变化时, // 重置与该用户关联的任何 state 部分。 - // 在这个简单的示例中,只是以电子邮件为例。 + // 在这个简单的示例中,只是以 email 为例。 if (props.userID !== state.prevUserID) { return { prevUserID: props.userID, @@ -1068,7 +1068,7 @@ class Form extends Component { -派生 state 会导致代码冗长,并使你的组件难以理解。 [确保你熟悉这些更简单的替代方案](https://legacy.reactjs.org/blog/2018/06/07/you-probously-dont-need-driven-state.html): +派生 state 会导致代码冗长,并使你的组件难以理解。[确保你熟悉这些更简单的替代方案](https://legacy.reactjs.org/blog/2018/06/07/you-probously-dont-need-driven-state.html): - 如果你需要 **执行副作用**(例如,数据获取或动画)以响应 props 的更改,请改用 [`componentDidUpdate`](#componentdidupdate) 方法。 - 如果你想 **仅在 prop 更改时重新计算一些数据**,[使用记忆助手代替](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization)。 @@ -1217,7 +1217,7 @@ button { display: block; margin-top: 10px; } 如果你定义了 [`componentDidMount`](#componentdidmount) 方法,当你的组件被添加到屏幕上(**挂载**)时,React 将会调用它。当你的组件由于 props 或 state 改变而重新渲染后,React 将调用 [`componentDidUpdate`](#componentdidupdate)。当你的组件从屏幕上被移除(**卸载**)后,React 将调用 [`componentWillUnmount`](#componentwillunmount)。 -如果你实现了 `componentDidMount`,通常需要实现所有三个生命周期以避免错误。例如,如果 `componentDidMount` 读取某些 state 或属性,你还必须实现 `componentDidUpdate` 来处理它们的更改,并实现 `componentWillUnmount` 来清理 `componentDidMount`所执行的所有操作。 +如果你实现了 `componentDidMount`,通常需要实现所有三个生命周期以避免错误。例如,如果 `componentDidMount` 读取某些 state 或属性,你还必须实现 `componentDidUpdate` 来处理它们的更改,并实现 `componentWillUnmount` 来清理 `componentDidMount` 所执行的所有操作。 例如,这个 `ChatRoom` 组件使聊天连接与 props 和 state 保持同步: @@ -1349,7 +1349,7 @@ button { margin-left: 10px; } 默认情况下,如果你的应用程序在渲染过程中抛出错误,React 将从屏幕上删除其 UI。为了防止这种情况,你可以将 UI 的一部分包装到 **错误边界** 中。错误边界是一个特殊的组件,可让你显示一些备用 UI,而不是例如错误消息这样崩溃的部分。 -要实现错误边界组件,你需要提供 [`static getDerivedStateFromError`](#static-getderivedstatefromerror),它允许你更新状态以响应错误并向用户显示错误消息。你还可以选择实现 [`componentDidCatch`](#componentdidcatch) 来添加一些额外的逻辑,例如,将错误记录到分析服务。 +要实现错误边界组件,你需要提供 [`static getDerivedStateFromError`](#static-getderivedstatefromerror),它允许你更新状态以响应错误并向用户显示错误消息。你还可以选择实现 [`componentDidCatch`](#componentdidcatch) 来添加一些额外的逻辑,例如将错误记录到分析服务。 ```js {7-10,12-19} class ErrorBoundary extends React.Component { @@ -1475,7 +1475,7 @@ export default function App() { --- -### 将具有状态的类组件迁移到函数 {/*migrating-a-component-with-state-from-a-class-to-a-function*/} +### 将具有 state 的类组件迁移到函数 {/*migrating-a-component-with-state-from-a-class-to-a-function*/} 假设你要将这个 `Counter` 从类组件转换为函数: @@ -1719,7 +1719,7 @@ button { margin-left: 10px; } 接下来, 验证你的 [`componentDidUpdate`](#componentdidupdate) 方法是否可以处理对 `componentDidMount` 中使用的任何 props 和 state 的更改。在上面的例子中,`componentDidMount` 调用 `setupConnection` 来读取 `this.state.serverUrl` 和 `this.props.roomId`。这就是为什么 `componentDidUpdate` 检查 `this.state.serverUrl` 和 `this.props.roomId` 是否已更改,如果更改了则重置连接。 如果你的 `componentDidUpdate` 逻辑丢失或无法处理所有相关 props 和 state 的更改,请首先修复该问题。 -在上面的示例中,生命周期方法内的逻辑将组件连接到 React 外部的系统(聊天服务器)。要将组件连接到外部系统,[将此逻辑描述为单个效果](/reference/react/useEffect#connecting-to-an-external-system): +在上面的示例中,生命周期方法内的逻辑将组件连接到 React 外部的系统(聊天服务器)。要将组件连接到外部系统,[请将此逻辑描述为单个效果](/reference/react/useEffect#connecting-to-an-external-system): ```js {6-12} import { useState, useEffect } from 'react'; @@ -1928,7 +1928,7 @@ export default function MyApp() { -当你将它们转换为函数组件时,将 `this.context` 用调用[`useContext`](/reference/react/useContext)来替换: +当你将它们转换为函数组件时,将 `this.context` 用调用 [`useContext`](/reference/react/useContext) 来替换: From a42a2f69003a5fd18351d128b9d6d313967ece60 Mon Sep 17 00:00:00 2001 From: Tosuke <1848228664@qq.com> Date: Fri, 14 Jul 2023 00:38:58 +0800 Subject: [PATCH 08/13] chore: fix most error --- src/content/reference/react/Component.md | 182 +++++++++++------------ 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index f5f1254492..f8fb51568c 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -109,17 +109,17 @@ class Greeting extends Component { -这个 API 将在未来 React 的主版本中被移除。 [使用 `createRef` 来代替](/reference/react/createRef)。 +这个 API 将在未来 React 的主版本中被移除。[使用 `createRef` 来代替](/reference/react/createRef)。 -允许你获取此组件的 [legacy string refs](https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs) +允许你获取此组件的 [过时的字符串 refs](https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs) --- ### `state` {/*state*/} -使用 `this.state` 来访问一个类组件的 state。 `state` 字段必须是一个对象。请不要直接改变 state 的值。如果你希望改变 state,那么请使用新的 state 来调用 `setState` 函数。 +使用 `this.state` 来访问一个类组件的 state。`state` 字段必须是一个对象。请不要直接改变 state 的值。如果你希望改变 state,那么请使用新的 state 来调用 `setState` 函数。 ```js {2-4,7-9,18} class Counter extends Component { @@ -184,31 +184,31 @@ class Counter extends Component { } ``` -constructor 不应该包含任何额外作用或者监听相关的代码。 +constructor 不应该包含任何副作用或者监听相关的代码。 #### 参数 {/*constructor-parameters*/} -* `props`: 组件初始的 props。 +* `props`:组件初始的 props。 #### 返回值 {/*constructor-returns*/} `constructor` 不应该返回任何东西。 -#### 说明 {/*constructor-caveats*/} +#### 注意 {/*constructor-caveats*/} * 不要在 constructor 中运行任何任额外作用或者监听相关的代码。相反,我们使用 [`componentDidMount`](#componentdidmount) 来解决这个问题。 -* 在 constructor 中,你需要在其他声明之前调用 `super(props)`。如果你不这样做,当 constructor 运行时 `this.props` 就会为 `undefined`, 这可能会造成困惑并且导致错误。 +* 在 constructor 中,你需要在其他声明之前调用 `super(props)`。如果你不这样做,当 constructor 运行时 `this.props` 就会为 `undefined`,这可能会造成困惑并且导致错误。 -* Constructor 是唯一一个你能直接赋值 [`this.state`](#state) 的地方。 在其余所有方法中,你需要使用 [`this.setState()`](#setstate) 来代替。不要使用在 constructor 中使用 `setState`。 +* Constructor 是唯一一个你能直接赋值 [`this.state`](#state) 的地方。在其余所有方法中,你需要使用 [`this.setState()`](#setstate) 来代替。不要使用在 constructor 中使用 `setState`。 -* 当你使用 [服务端渲染](/reference/react-dom/server) 时,constructor 也将在服务端运行,紧接着运行 [`render`](#render) 方法。 然而,像是 `componentDidMount` 或者 `componentWillUnmount` 这样的生命周期方法将不会在服务端运行。 +* 当你使用 [服务端渲染](/reference/react-dom/server) 时,constructor 也将在服务端运行,紧接着运行 [`render`](#render) 方法。然而,像是 `componentDidMount` 或者 `componentWillUnmount` 这样的生命周期方法将不会在服务端运行。 -* 当 [严格模式](/reference/react/StrictMode) 打开时, React 将会在开发过程中调用两次 `constructor` 然后丢弃其中的一个实例。这有助于你注意到需要从 `constructor` 中移出的意外副作用。 +* 当 [严格模式](/reference/react/StrictMode) 打开时,React 将会在开发过程中调用两次 `constructor` 然后丢弃其中的一个实例。这有助于你注意到需要从 `constructor` 中移出的意外副作用。 -在函数组件中没有与 `constructor` 作用完全相同的函数。 要在函数组件中声明 state 请调用 [`useState`](/reference/react/useState) 来避免重新计算初始的 state。[传递一个函数给 `useState`](/reference/react/useState#avoiding-recreating-the-initial-state)。 +在函数组件中没有与 `constructor` 作用完全相同的函数。要在函数组件中声明 state 请调用 [`useState`](/reference/react/useState) 来避免重新计算初始的 state。[传递一个函数给 `useState`](/reference/react/useState#avoiding-recreating-the-initial-state)。 @@ -224,23 +224,23 @@ constructor 不应该包含任何额外作用或者监听相关的代码。 #### 参数 {/*componentdidcatch-parameters*/} -* `error`: 被抛出的错误。实际上,它通常会是一个 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,不过这并不能保证,因为 JavaScript 允许 [`抛出`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 所有类型的值,包括字符串甚至是 `null`。 +* `error`:被抛出的错误。实际上,它通常会是一个 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,不过这并不能保证,因为 JavaScript 允许 [`抛出`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 所有类型的值,包括字符串甚至是 `null`。 -* `info`: 一个包含有关错误的附加信息的对象。它的 `componentStack` 字段包含一个堆栈跟踪,其中包含抛出的组件,以及其所有父组件的名称和源位置。在生产中,组件名称将被简化。如果你设置了生产错误报告服务,则可以使用源映射来解码组件堆栈,就像处理常规 JavaScript 错误堆栈一样。 +* `info`:一个包含有关错误的附加信息的对象。它的 `componentStack` 字段包含一个堆栈跟踪,其中包含抛出的组件,以及其所有父组件的名称和源位置。在生产中,组件名称将被简化。如果你设置了生产错误报告服务,则可以使用源映射来解码组件堆栈,就像处理常规 JavaScript 错误堆栈一样。 #### 返回值 {/*componentdidcatch-returns*/} `componentDidCatch` 不应该返回任何值。 -#### 说明 {/*componentdidcatch-caveats*/} +#### 注意 {/*componentdidcatch-caveats*/} * 在以前经常会在 `componentDidCatch` 中使用 `setState` 来更新UI以及显示回退错误消息。这现在已被废弃,我们更赞同定义 [`static getDerivedStateFromError`](#static-getderivedstatefromerror)。 -* React 的生产和开发版本在 `componentDidCatch` 处理错误的方式有所不同,在开发环境下,错误将冒泡至 `window`,这意味着任何 `window.onerror` 或者 `window.addEventListener('error', callback)` 都将中断被 `componentDidCatch` 所捕获到的错误。而在生产环境下相反,错误并不会冒泡, 这意味着任何祖先级的错误处理器都只会接收到被 `componentDidCatch` 捕获的非显式错误。 +* React 的生产和开发版本在 `componentDidCatch` 处理错误的方式有所不同,在开发环境下,错误将冒泡至 `window`,这意味着任何 `window.onerror` 或者 `window.addEventListener('error', callback)` 都将中断被 `componentDidCatch` 所捕获到的错误。而在生产环境下相反,错误并不会冒泡,这意味着任何祖先级的错误处理器都只会接收到被 `componentDidCatch` 捕获的非显式错误。 -在函数组件中没有与 `componentDidCatch` 作用完全相同的函数。如果你想要避免创建类组件,那么可以单独写一个像上面一样的 `错误边界` 并在整个应用中使用它。 又或者,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包,它可以完成同样的工作。 +在函数组件中没有与 `componentDidCatch` 作用完全相同的函数。如果你想要避免创建类组件,那么可以单独写一个像上面一样的 `错误边界` 并在整个应用中使用它。又或者,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包,它可以完成同样的工作。 @@ -248,9 +248,9 @@ constructor 不应该包含任何额外作用或者监听相关的代码。 ### `componentDidMount()` {/*componentdidmount*/} -如果你定义了 `componentDidMount` 方法, React 将会在你的组件添加上屏幕 **(挂载后)** 时调用它。这里是设置数据获取、设置监听或操作DOM节点的常见位置。 +如果你定义了 `componentDidMount` 方法,React 将会在你的组件添加上屏幕 **(挂载后)** 时调用它。这里是设置数据获取、设置监听或操作DOM节点的常见位置。 -如果你要执行 `componentDidMount`,你通常需要设置一些其他的生命周期函数来避免出错。例如,如果 `componentDidMount` 读取一些 state 或者 props,你还必须要设置 [`componentDidUpdate`](#componentdidupdate) 来处理它们的更新, 以及设置 [`componentWillUnmount`](#componentwillunmount) 来清理 `componentDidMount` 的效果。 +如果你要执行 `componentDidMount`,你通常需要设置一些其他的生命周期函数来避免出错。例如,如果 `componentDidMount` 读取一些 state 或者 props,你还必须要设置 [`componentDidUpdate`](#componentdidupdate) 来处理它们的更新,以及设置 [`componentWillUnmount`](#componentwillunmount) 来清理 `componentDidMount` 的效果。 ```js {6-8} class ChatRoom extends Component { @@ -290,11 +290,11 @@ class ChatRoom extends Component { `componentDidMount` 不应该返回任何值。 -#### 说明 {/*componentdidmount-caveats*/} +#### 注意 {/*componentdidmount-caveats*/} -- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发环境中 React 会调用 `componentDidMount`,然后会立刻调用 [`componentWillUnmount`](#componentwillunmount), 接着再次调用 `componentDidMount`。 这将帮助你注意到你是否忘记设置 `componentWillUnmount` 或者它的逻辑是否完全对应到 `componentDidMount` 的效果。 +- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发环境中 React 会调用 `componentDidMount`,然后会立刻调用 [`componentWillUnmount`](#componentwillunmount),接着再次调用 `componentDidMount`。这将帮助你注意到你是否忘记设置 `componentWillUnmount` 或者它的逻辑是否完全对应到 `componentDidMount` 的效果。 -- 虽然你可以在 `componentDidMount` 中立即调用 [`setState`](#setstate),不过最好避免这样做。 因为这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。在这种情况下即使 [`render`](#render) 被调用了两次,用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下,你应该能在 [`constructor`](#constructor) 中设置初始的 state。 但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 +- 虽然你可以在 `componentDidMount` 中立即调用 [`setState`](#setstate),不过最好避免这样做。因为这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。在这种情况下即使 [`render`](#render) 被调用了两次,用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下,你应该能在 [`constructor`](#constructor) 中设置初始的 state。但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 @@ -345,27 +345,27 @@ class ChatRoom extends Component { #### 参数 {/*componentdidupdate-parameters*/} -* `prevProps`: 更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`:更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: 更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`:更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 -* `snapshot`: 如果你设置了 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 方法,那么 `snapshot` 将包含从该方法返回的值。否则它将是 `undefined`。 +* `snapshot`:如果你设置了 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 方法,那么 `snapshot` 将包含从该方法返回的值。否则它将是 `undefined`。 #### 返回值 {/*componentdidupdate-returns*/} `componentDidUpdate` 不应该返回任何值。 -#### 说明 {/*componentdidupdate-caveats*/} +#### 注意 {/*componentdidupdate-caveats*/} -- 如果你定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并且返回 false 的话,那么 `componentDidUpdate` 将不会被调用。 +- 如果你定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并且返回 `false` 的话,那么 `componentDidUpdate` 将不会被调用。 - `componentDidUpdate` 内部的逻辑通常应该包含在比较 `this.props` 与 `prevProps` 以及 `this.state` 与 `prevState` 之中。否则就会存在创建无限循环的风险。 -- 虽然可以在 `componentDidUpdate` 中立即调用 [`setState`](#setstate),但最好尽可能避免这样做。它将触发一个额外的渲染,但它将在浏览器更新屏幕之前发生。这导致了即使 [`render`](#render) 在这种情况下会被调用两次,用户也看不到中间状态。这种模式通常会导致性能问题,但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 +- 虽然可以在 `componentDidUpdate` 中立即调用 [`setState`](#setstate),但最好尽可能避免这样做。它将触发一个额外的渲染,但它是在浏览器更新屏幕之前发生的。这导致了即使 [`render`](#render) 在这种情况下会被调用两次,用户也看不到中间状态。这种模式通常会导致性能问题,但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 -对于大多数用例来说, 在类组件中一起定义 `componentDidMount`,`componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中定义 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于[`useLayoutEffect`](/reference/react/useLayoutEffect)。 +对于大多数用例来说,在类组件中一起定义 `componentDidMount`,`componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中定义 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -378,7 +378,7 @@ class ChatRoom extends Component { 此 API 已从 `componentWillMount` 重命名为 [`UNSAFE_componentWillMount`](#unsafe_componentwillmount)。旧名称已被弃用,在 React 未来主要的版本中,只有新名称才有效。 -运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 +运行 [`rename-unsafe-lifecycles` 重构器](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -390,7 +390,7 @@ class ChatRoom extends Component { 此 API 已从 `componentWillReceiveProps` 重命名为 [`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops)。旧名称已被弃用,在 React 未来主要的版本中,只有新名称才有效。 -运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 +运行 [`rename-unsafe-lifecycles` 重构器](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -402,7 +402,7 @@ class ChatRoom extends Component { 此 API 已从 `componentWillUpdate` 重命名为 [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate)。旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 -运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 +运行 [`rename-unsafe-lifecycles` 重构器](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -410,9 +410,9 @@ class ChatRoom extends Component { ### `componentWillUnmount()` {/*componentwillunmount*/} -如果你定义了 `componentWillUnmount` 方法,React 会在你的组件被移除屏幕 **(卸载)** 之前调用它。这是取消数据获取或删除监听的常见位置。 +如果你定义了 `componentWillUnmount` 方法,React 会在你的组件被移除屏幕(**卸载**)之前调用它。这是取消数据获取或删除监听的常用位置。 -`componentWillUnmount` 内部的逻辑应该完全对应 [`componentDidMount`](#componentdidmount) 内部的逻辑,例如,如果你在 `componentDidMount` 中设置了一个监听,那么 `componentWillUnmount` 中就应该清除掉这个监听。如果你的 `componentWillUnmount` 的清理逻辑中读取了一些 props 或者 state,那么你通常还需要实现一个 [`componentDidUpdate`](#componentdidupdate) 来清理使用了旧 props 和 state 的资源(例如监听)。 +`componentWillUnmount` 内部的逻辑应该完全“对应”到 [`componentDidMount`](#componentdidmount) 内部的逻辑,例如,如果你在 `componentDidMount` 中设置了一个监听,那么 `componentWillUnmount` 中就应该清除掉这个监听。如果你的 `componentWillUnmount` 的清理逻辑中读取了一些 props 或者 state,那么你通常还需要实现一个 [`componentDidUpdate`](#componentdidupdate) 来清理使用了旧 props 和 state 的资源(例如监听)。 ```js {20-22} class ChatRoom extends Component { @@ -452,13 +452,13 @@ class ChatRoom extends Component { `componentWillUnmount` 不应该返回任何值。 -#### 说明 {/*componentwillunmount-caveats*/} +#### 注意 {/*componentwillunmount-caveats*/} - 当 [严格模式](/reference/react/StrictMode) 开启时,在开发中 React 会调用 [`componentDidMount`](#componentdidmount) 然后立即调用 `componentWillUnmount`,接着再次调用 `componentDidMount`。这可以帮助你注意到你是否忘记实现 `componentWillUnmount`,或者它的逻辑是否没有完全对应到 `componentDidMount` 的效果。 -对于许多用例,在类组件中一起定义 `componentDidMount`、`componentDidUpdate` 和 `componentWillUnmount` 相当于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 +对于许多用例来说,在类组件中一起定义 `componentDidMount`、`componentDidUpdate` 和 `componentWillUnmount` 相当于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -482,9 +482,9 @@ class ChatRoom extends Component { `forceUpdate` 不返回任何值。 -#### 说明 {/*forceupdate-caveats*/} +#### 注意 {/*forceupdate-caveats*/} -- 如果你调用了 `forceUpdate`, React 将重新渲染而且不会调用 [`shouldComponentUpdate`](#shouldComponentupdate)。 +- 如果你调用了 `forceUpdate`,React 将重新渲染而且不会调用 [`shouldComponentUpdate`](#shouldComponentupdate)。 @@ -498,7 +498,7 @@ class ChatRoom extends Component { -该 API 将在 React 未来主要的版本中删除。 [使用 `Context.Provider` 代替](/reference/react/createContext#provider)。 +该 API 将在 React 未来主要的版本中删除。[使用 `Context.Provider` 代替](/reference/react/createContext#provider)。 @@ -532,7 +532,7 @@ class ScrollingList extends React.Component { componentDidUpdate(prevProps, prevState, snapshot) { // 如果我们有快照值,那么我们刚刚添加了新项目。 // 调整滚动,使这些新项目不会将旧项目推出视野。 - // (这里的snapshot是getSnapshotBeforeUpdate返回的值) + // (这里的 snapshot 是 getSnapshotBeforeUpdate 返回的值) if (snapshot !== null) { const list = this.listRef.current; list.scrollTop = list.scrollHeight - snapshot; @@ -551,21 +551,21 @@ class ScrollingList extends React.Component { #### 参数 {/*getsnapshotbeforeupdate-parameters*/} -* `prevProps`: 更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`:更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: 更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`:更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 #### 返回值 {/*getsnapshotbeforeupdate-returns*/} 你应该返回你想要的任何类型的快照值,或者是 `null`。你返回的值将作为第三个参数传递给 [`componentDidUpdate`](#componentdidupdate)。 -#### 说明 {/*getsnapshotbeforeupdate-caveats*/} +#### 注意 {/*getsnapshotbeforeupdate-caveats*/} - 如果你定义了 [`shouldComponentUpdate`](#shouldcomponentUpdate) 并返回了 `false`,则 `getSnapshotBeforeUpdate` 不会被调用。 -目前,函数组件中还没有与 `getSnapshotBeforeUpdate` 等同的方法。这种使用场景非常罕见,但如果你有需要,那么你就必须编写一个类组件。 +目前,函数组件中还没有与 `getSnapshotBeforeUpdate` 等同的方法。这种使用场景非常罕见,但如果你有这种需求,那么你就必须编写一个类组件。 @@ -587,27 +587,27 @@ class Greeting extends Component { } ``` -React 可能随时调用 `render`,因此你不应该假设它在特定时间运行。一般来说, `render` 方法应该返回一段 [JSX](/learn/writing-markup-with-jsx),但也支持一些 [其他返回类型](#render-returns)(如字符串)。为了计算返回的 JSX,`render` 方法可以读取 [`this.props`](#props)、[`this.state`](#state) 和 [`this.context`](#context)。 +React 可能随时调用 `render`,因此你不应该假设它在特定时间运行。一般来说,`render` 方法应该返回一段 [JSX](/learn/writing-markup-with-jsx),但也支持一些 [其他的返回类型](#render-returns)(如字符串)。为了计算返回的 JSX,`render` 方法可以读取 [`this.props`](#props)、[`this.state`](#state) 和 [`this.context`](#context)。 -你应该将 `render` 方法编写为纯函数,这意味着如果 props、state 和 context 相同,它应该返回相同的结果。它也不应该包含额外的作用(例如设置监听)或与浏览器 API 交互。额外的作用应该发生在事件处理程序或 [`componentDidMount`](#componentdidmount) 等方法中。 +你应该将 `render` 方法编写为纯函数,这意味着如果 props、state 和 context 相同,它应该返回相同的结果。它也不应该包含副作用(例如设置监听)或与浏览器 API 交互。副作用应该发生在事件处理程序或 [`componentDidMount`](#componentdidmount) 等方法中。 #### 参数 {/*render-parameters*/} -* `prevProps`: 更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`:更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 -* `prevState`: 更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`:更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 #### 返回值 {/*render-returns*/} -`render` 可以返回任何有效的 React 节点。这包括 React 元素,例如 `
`、字符串、数字、[portals](/reference/react-dom/createPortal)、空节点(`null`、`undefined`、`true` 和 `false`)和 React 节点数组。 +`render` 可以返回任何有效的 React 节点。其中包括 React 元素,例如 `
`、字符串、数字、[portals](/reference/react-dom/createPortal)、空节点(`null`、`undefined`、`true` 和 `false`)以及 React 节点数组。 -#### 说明 {/*render-caveats*/} +#### 注意 {/*render-caveats*/} -- `render` 应该写成关于 props、state 和 context 的纯函数,它不应该包含额外的作用。 +- `render` 应该写成关于 props、state 和 context 的纯函数,它不应该包含副作用。 -- 如果定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并返回 `false`,则 `render` 不会被调用。 +- 如果定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并返回 `false` 的话,则 `render` 不会被调用。 -- 当 [严格模式](/reference/react/StrictMode) 开启时,React 将在开发过程中调用 `render` 两次,然后丢弃其中一个结果。这可以帮助你注意到需要从 `render` 方法中移出的意外的副作用。 +- 当 [严格模式](/reference/react/StrictMode) 开启时,React 将在开发过程中调用两次 `render`,然后丢弃其中一个结果。这可以帮助你注意到需要从 `render` 方法中移出的意外的副作用。 - `render` 调用和后续的 `componentDidMount` 或 `componentDidUpdate` 调用之间没有一一对应的关系。React 可能会在有益的情况下丢弃一些 `render` 的调用结果。 --- @@ -645,7 +645,7 @@ class Form extends Component { -调用 `setState` 时 **不会** 更改已执行代码中的当前状态: +调用 `setState` 时 **不会** 更改已执行代码中的当前 state: ```js {6} function handleClick() { @@ -677,17 +677,17 @@ function handleClick() { #### 参数 {/*setstate-parameters*/} -* `nextState`: 一个对象或者函数。 +* `nextState`:一个对象或者函数。 * 如果你传递一个对象作为 `nextState`,它将浅层合并到 `this.state` 中。 * 如果你传递一个函数作为 `nextState`,它将被视为 **更新函数**。它必须是个纯函数,应该以已加载的 state 和 props 作为参数,并且应该返回要浅层合并到 `this.state` 中的对象。React 会将你的更新函数放入队列中并重新渲染你的组件。在下一次渲染期间,React 将通过应用队列中的所有更新程序来计算下一个 state。 -* **可选的** `callback`: 如果你指定,React 将在提交更新后调用你提供的`回调函数`。 +* **可选的** `callback`:如果你指定,React 将在提交更新后调用你提供的`回调函数`。 #### 返回值 {/*setstate-returns*/} `setState` 不会返回任何值。 -#### 说明 {/*setstate-caveats*/} +#### 注意 {/*setstate-caveats*/} - 将 `setState` 视为 **请求**,而不是立即会更新组件的命令。当多个组件更新它们的 state 以响应事件时,React 将批量更新它们,并在这次事件结束时将它们一并重新渲染。在极少数情况下,你需要强制同步应用特定的状态更新,你可以将其包装在 [`flushSync`](/reference/react-dom/flushSync) 中,但这可能会损害性能。 @@ -734,13 +734,13 @@ class Rectangle extends Component { ``` -当收到新的 props 或 state 时,React 会在渲染之前调用 `shouldComponentUpdate`,默认为 `true`。初始渲染或使用 [`forceUpdate`](#forceupdate) 时将不会调用此方法。 +当收到新的 props 或 state 时,React 会在渲染之前调用 `shouldComponentUpdate`,默认值为 `true`。初始渲染或使用 [`forceUpdate`](#forceupdate) 时将不会调用此方法。 #### 参数 {/*shouldcomponentupdate-parameters*/} -- `nextProps`: 组件即将用来渲染的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 -- `nextState`: 组件即将渲染的下一个 state。将 `nextState` 与 [`this.state`](#props) 进行比较以确定发生了什么变化。 -- `nextContext`: 组件将要渲染的下一个 context。将 `nextContext` 与 [`this.context`](#context) 进行比较以确定发生了什么变化。仅当你指定了 [`static contextType`](#static-contexttype)(更新的)或 [`static contextTypes`](#static-contexttypes)(旧版)时才可用。 +- `nextProps`:组件即将用来渲染的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 +- `nextState`:组件即将渲染的下一个 state。将 `nextState` 与 [`this.state`](#props) 进行比较以确定发生了什么变化。 +- `nextContext`:组件将要渲染的下一个 context。将 `nextContext` 与 [`this.context`](#context) 进行比较以确定发生了什么变化。仅当你指定了 [`static contextType`](#static-contexttype)(更新的)或 [`static contextTypes`](#static-contexttypes)(旧版)时才可用。 #### 返回值 {/*shouldcomponentupdate-returns*/} @@ -748,7 +748,7 @@ class Rectangle extends Component { 返回 `false` 来告诉 React 可以跳过重新渲染。 -#### 说明 {/*shouldcomponentupdate-caveats*/} +#### 注意 {/*shouldcomponentupdate-caveats*/} - 此方法 **仅仅** 作为性能优化而存在。如果你的组件在没有它的情况下损坏,请先修复组件。 @@ -785,11 +785,11 @@ class Rectangle extends Component { `UNSAFE_componentWillMount` 不应该返回任何值。 -#### 说明 {/*unsafe_componentwillmount-caveats*/} +#### 注意 {/*unsafe_componentwillmount-caveats*/} - 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillMount`。 -- 即使它的名字是这样的,但是如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等现代 React 功能时,`UNSAFE_componentWillMount` 不保证组件 **将** 被挂载。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),那么 React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。这就是为什么这种方法是 **不安全** 的。依赖于挂载(例如添加监听)的代码应放入 [`componentDidMount`](#componentdidmount)。 +- 即使它的名字是这样的,但是如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等新式的 React 功能时,`UNSAFE_componentWillMount` 不保证组件 **将** 被挂载。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),那么 React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。这就是为什么这种方法是 **不安全** 的。依赖于挂载(例如添加监听)的代码应放入 [`componentDidMount`](#componentdidmount)。 - `UNSAFE_componentWillMount` 是运行 [服务器渲染](/reference/react-dom/server) 期间运行的唯一生命周期方法。对于所有实际用途来说,它与 [`constructor`](#constructor) 相同,因此你应该使用 `constructor` 来代替这种类型的逻辑。 @@ -807,25 +807,25 @@ class Rectangle extends Component { - 如果你需要 **运行额外作用**(例如,获取数据、运行动画或重新初始化监听)来响应 prop 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate)。 - 如果你需要 **避免仅在 prop 更改时重新计算某些数据** 时,请使用 [memoization helper](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization) 来代替。 -- 如果你需要 **在 prop 更改时`重置`某些状态** 时,请考虑使组件 [完全控制](https://legacy.reactjs.org/blog/2018/06/07/you-probously-不需要派生状态。html#recommendation-fully-controlled-component) 或者 [使用 key 使组件完全不受控](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) 代替。 +- 如果你需要 **在 prop 更改时`重置`某些状态** 时,请考虑使组件 [完全控制](https://legacy.reactjs.org/blog/2018/06/07/you-probously-不需要派生状态。html#recommendation-fully-controlled-component) 或者 [使用 key 使组件完全不受控](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) 来代替。 - 如果你需要 **在 prop 更改时`调整`某些状态,** 检查你是否可以在渲染期间单独从 props 计算所有必要的信息。如果不能,请使用 [`static getDerivedStateFromProps`](/reference/react/Component#static-getdrivenstatefromprops) 代替。 [查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props)。 #### 参数 {/*unsafe_componentwillreceiveprops-parameters*/} -- `nextProps`: 组件将从其父组件接收的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 -- `nextContext`: 组件将从最近的提供者处接收的下一个 props。将 `nextContext` 与 [`this.context`](#context) 进行比较以确定发生了什么变化。仅当你指定 [`static contextType`](#static-contexttype)(更新的)或 [`static contextTypes`](#static-contexttypes)(旧版)时才可用。 +- `nextProps`:组件将从其父组件接收的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 +- `nextContext`:组件将从最近的提供者处接收的下一个 props。将 `nextContext` 与 [`this.context`](#context) 进行比较以确定发生了什么变化。仅当你指定 [`static contextType`](#static-contexttype)(更新的)或 [`static contextTypes`](#static-contexttypes)(旧版)时才可用。 #### 返回值 {/*unsafe_componentwillreceiveprops-returns*/} `UNSAFE_componentWillReceiveProps` 不应该返回任何值。 -#### 说明 {/*unsafe_componentwillreceiveprops-caveats*/} +#### 注意 {/*unsafe_componentwillreceiveprops-caveats*/} - 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillReceiveProps`。 -- 即使它的名字是这样的, 但如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等现代 React 功能时,`UNSAFE_componentWillReceiveProps` 不保证组件 **将会** 接收这些 Props。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,Props 可能会有所不同。这就是为什么这种方法 **不安全**。仅为更新(例如重置监听)的代码应放入 [`componentDidUpdate`](#componentdidupdate)。 +- 即使它的名字是这样的,但如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等新式的 React 功能时,`UNSAFE_componentWillReceiveProps` 不保证组件 **将会** 接收这些 Props。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,Props 可能会有所不同。这就是为什么这种方法 **不安全**。仅为更新(例如重置监听)的代码应放入 [`componentDidUpdate`](#componentdidupdate)。 - `UNSAFE_componentWillReceiveProps` 并不意味着组件收到了与上次 **不同的** props。你需要自己比较 `nextProps` 和 `this.props` 以检查是否发生了变化。 @@ -833,7 +833,7 @@ class Rectangle extends Component { -在类组件中的 `UNSAFE_componentWillReceiveProps` 里调用 [`setState`](#setstate) 来“调整” state 等同于在函数组件在 [渲染期间从 `useState` 调用 `set` 函数](/reference/react/useState#storing-information-from-previous-renders)。 +在类组件中的 `UNSAFE_componentWillReceiveProps` 里调用 [`setState`](#setstate) 来“调整”state 等同于在函数组件在 [渲染期间从 `useState` 调用 `set` 函数](/reference/react/useState#storing-information-from-previous-renders)。 @@ -851,14 +851,14 @@ class Rectangle extends Component { #### 参数 {/*unsafe_componentwillupdate-parameters*/} -- `nextProps`: 组件即将用来渲染的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 -- `nextState`: 组件即将渲染的下一个 state。将 `nextState` 与 [`this.state`](#state) 进行比较以确定发生了什么变化。 +- `nextProps`:组件即将用来渲染的下一个 props。将 `nextProps` 与 [`this.props`](#props) 进行比较以确定发生了什么变化。 +- `nextState`:组件即将渲染的下一个 state。将 `nextState` 与 [`this.state`](#state) 进行比较以确定发生了什么变化。 #### 返回值 {/*unsafe_componentwillupdate-returns*/} `UNSAFE_componentWillUpdate` 不应该返回任何值。 -#### 说明 {/*unsafe_componentwillupdate-caveats*/} +#### 注意 {/*unsafe_componentwillupdate-caveats*/} - 如果定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并返回 `false`,则 `UNSAFE_componentWillUpdate` 将不会被调用。 @@ -866,7 +866,7 @@ class Rectangle extends Component { - 不支持在 `componentWillUpdate` 期间调用 [`setState`](#setstate)(或任何导致调用 `setState` 的方法,例如调度 Redux 操作)。 -- 尽管它的命名是这样,但如果你的应用程序使用如 [`Suspense`](/reference/react/Sus​​pense) 时等现代 React 功能时,`UNSAFE_componentWillUpdate` 并不能保证组件 **将会** 更新。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,props 和 state 可能会有所不同。 这就是为什么这种方法“不安全”。仅针对更新(例如重置监听)运行的代码应放入 [`componentDidUpdate`](#componentdidupdate)。 +- 尽管它的命名是这样,但如果你的应用程序使用如 [`Suspense`](/reference/react/Sus​​pense) 时等新式的 React 功能时,`UNSAFE_componentWillUpdate` 并不能保证组件 **将会** 更新。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,props 和 state 可能会有所不同。这就是为什么这种方法“不安全”。仅针对更新(例如重置监听)运行的代码应放入 [`componentDidUpdate`](#componentdidupdate)。 - `UNSAFE_componentWillUpdate` 并不意味着组件收到了与上次不同的 props 或 state。你需要自己将 `nextProps` 与 `this.props` 以及 `nextState` 与 `this.state` 进行比较,以检查是否发生了变化。 @@ -888,7 +888,7 @@ class Rectangle extends Component { -允许你指定此组件提供哪个 [旧版 context](https://reactjs.org/docs/legacy-context.html)。 +允许你指定此组件提供哪个 [过时的 context](https://reactjs.org/docs/legacy-context.html)。 --- @@ -900,7 +900,7 @@ class Rectangle extends Component { -允许你指定此组件使用哪个 [旧版 context](https://reactjs.org/docs/legacy-context.html)。 +允许你指定此组件使用哪个 [过时的 context](https://reactjs.org/docs/legacy-context.html)。 --- @@ -956,16 +956,16 @@ class Button extends Component { ```js <> - {/* this.props.color is "blue" */} + {/* this.props.color 为 “blue” */} -

You are {this.state.age}.

+

你{this.state.age}岁了。

); } @@ -148,7 +148,7 @@ class Counter extends Component { -在类组件中定义 `state` 等同于在函数组件中通过调用 [`useState`](/reference/react/useState) 函数所创造的 state。 +在类式组件中定义 `state` 等同于在函数式组件中通过调用 [`useState`](/reference/react/useState) 函数所创造的 state。 [了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function)。 @@ -158,7 +158,7 @@ class Counter extends Component { ### `constructor(props)` {/*constructor*/} -[constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor) 会在你的类组件 **挂载**(添加到屏幕上)之前运行。一般来说,在 React 中 constructor 仅用于两个目的。它可以让你来声明 state 以及将你的类方法 [绑定](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind) 到你的类实例上。 +[constructor](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/constructor) 会在你的类式组件 **挂载**(添加到屏幕上)之前运行。一般来说,在 React 中 constructor 仅用于两个目的。它可以让你来声明 state 以及将你的类方法 [绑定](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_objects/Function/bind) 到你的类实例上。 ```js {2-6} class Counter extends Component { @@ -173,7 +173,7 @@ class Counter extends Component { } ``` -如果你使用更新的 JavaScript 语法的话,那么很少需要使用到 constructors。相反,你可以使用现代浏览器和像 [Babel](https://babeljs.io/) 这样的工具都支持的 [公有类字段语法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields) 来重写上面的代码。 +如果你使用较新的 JavaScript 语法的话,那么很少需要使用到 constructors。现代浏览器和像 [Babel](https://babeljs.io/) 这样的工具都支持的 [公有类字段语法](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/Public_class_fields),你可以使用它们来重写上面的代码。 ```js {2,4} class Counter extends Component { @@ -192,23 +192,23 @@ constructor 不应该包含任何副作用或者监听相关的代码。 #### 返回值 {/*constructor-returns*/} -`constructor` 不应该返回任何东西。 +`constructor` 不应该返回任何值。 #### 注意 {/*constructor-caveats*/} -* 不要在 constructor 中运行任何任额外作用或者监听相关的代码。相反,我们使用 [`componentDidMount`](#componentdidmount) 来解决这个问题。 +* 不要在 constructor 中运行任何任额外作用或者监听相关的代码。使用 [`componentDidMount`](#componentdidmount) 来应对这种需求。 + +* 在 constructor 中,你需要在其他声明之前调用 `super(props)`。如果你不这样做,`this.props` 在 constructor 运行时就会是 `undefined`,这可能会造成困惑并且导致错误。 -* 在 constructor 中,你需要在其他声明之前调用 `super(props)`。如果你不这样做,当 constructor 运行时 `this.props` 就会为 `undefined`,这可能会造成困惑并且导致错误。 - * Constructor 是唯一一个你能直接赋值 [`this.state`](#state) 的地方。在其余所有方法中,你需要使用 [`this.setState()`](#setstate) 来代替。不要使用在 constructor 中使用 `setState`。 -* 当你使用 [服务端渲染](/reference/react-dom/server) 时,constructor 也将在服务端运行,紧接着运行 [`render`](#render) 方法。然而,像是 `componentDidMount` 或者 `componentWillUnmount` 这样的生命周期方法将不会在服务端运行。 +* 当你使用 [服务端渲染](/reference/react-dom/server) 时,constructor 也将在服务端运行,紧接着运行 [`render`](#render) 方法。然而,像 `componentDidMount` 或者 `componentWillUnmount` 这样的生命周期方法将不会在服务端运行。 * 当 [严格模式](/reference/react/StrictMode) 打开时,React 将会在开发过程中调用两次 `constructor` 然后丢弃其中的一个实例。这有助于你注意到需要从 `constructor` 中移出的意外副作用。 -在函数组件中没有与 `constructor` 作用完全相同的函数。要在函数组件中声明 state 请调用 [`useState`](/reference/react/useState) 来避免重新计算初始的 state。[传递一个函数给 `useState`](/reference/react/useState#avoiding-recreating-the-initial-state)。 +在函数式组件中没有与 `constructor` 作用完全相同的函数。要在函数式组件中声明 state 请调用 [`useState`](/reference/react/useState) 来避免重新计算初始的 state。[传递一个函数给 `useState`](/reference/react/useState#avoiding-recreating-the-initial-state)。 @@ -224,7 +224,7 @@ constructor 不应该包含任何副作用或者监听相关的代码。 #### 参数 {/*componentdidcatch-parameters*/} -* `error`:被抛出的错误。实际上,它通常会是一个 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,不过这并不能保证,因为 JavaScript 允许 [`抛出`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 所有类型的值,包括字符串甚至是 `null`。 +* `error`:被抛出的错误。实际上,它通常会是一个 [`Error`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,不过这并不能保证,因为 JavaScript 允许 [`抛出`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/throw) 所有类型的值,包括字符串甚至是 `null`。 * `info`:一个包含有关错误的附加信息的对象。它的 `componentStack` 字段包含一个堆栈跟踪,其中包含抛出的组件,以及其所有父组件的名称和源位置。在生产中,组件名称将被简化。如果你设置了生产错误报告服务,则可以使用源映射来解码组件堆栈,就像处理常规 JavaScript 错误堆栈一样。 @@ -236,11 +236,11 @@ constructor 不应该包含任何副作用或者监听相关的代码。 * 在以前经常会在 `componentDidCatch` 中使用 `setState` 来更新UI以及显示回退错误消息。这现在已被废弃,我们更赞同定义 [`static getDerivedStateFromError`](#static-getderivedstatefromerror)。 -* React 的生产和开发版本在 `componentDidCatch` 处理错误的方式有所不同,在开发环境下,错误将冒泡至 `window`,这意味着任何 `window.onerror` 或者 `window.addEventListener('error', callback)` 都将中断被 `componentDidCatch` 所捕获到的错误。而在生产环境下相反,错误并不会冒泡,这意味着任何祖先级的错误处理器都只会接收到被 `componentDidCatch` 捕获的非显式错误。 +* `componentDidCatch` 在 React 生产环境和开发环境中处理错误的方式有所不同,在开发环境下,错误将冒泡至 `window`,这意味着任何 `window.onerror` 或者 `window.addEventListener('error', callback)` 都中断被 `componentDidCatch` 所捕获到的错误。而在生产环境下则相反,错误并不会冒泡,这意味着任何父级的错误处理器都只会接收到被 `componentDidCatch` 捕获的非显式错误。 -在函数组件中没有与 `componentDidCatch` 作用完全相同的函数。如果你想要避免创建类组件,那么可以单独写一个像上面一样的 `错误边界` 并在整个应用中使用它。又或者,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包,它可以完成同样的工作。 +在函数式组件中没有与 `componentDidCatch` 作用完全相同的函数。如果你想要避免创建类式组件,那么可以单独写一个像上面一样的 `错误边界` 并在整个应用中使用它。又或者,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包,它可以完成同样的工作。 @@ -248,9 +248,9 @@ constructor 不应该包含任何副作用或者监听相关的代码。 ### `componentDidMount()` {/*componentdidmount*/} -如果你定义了 `componentDidMount` 方法,React 将会在你的组件添加上屏幕 **(挂载后)** 时调用它。这里是设置数据获取、设置监听或操作DOM节点的常见位置。 +如果你定义了 `componentDidMount` 方法,React 将会在组件被添加到屏幕上 **(挂载)** 后调用它。这里是设置数据获取、订阅监听事件或操作DOM节点的常见位置。 -如果你要执行 `componentDidMount`,你通常需要设置一些其他的生命周期函数来避免出错。例如,如果 `componentDidMount` 读取一些 state 或者 props,你还必须要设置 [`componentDidUpdate`](#componentdidupdate) 来处理它们的更新,以及设置 [`componentWillUnmount`](#componentwillunmount) 来清理 `componentDidMount` 的效果。 +如果你要实现 `componentDidMount`,你通常需要设置一些其他的生命周期函数来避免出错。例如,如果 `componentDidMount` 读取一些 state 或者 props,你还必须要设置 [`componentDidUpdate`](#componentdidupdate) 来处理它们的更新,以及设置 [`componentWillUnmount`](#componentwillunmount) 来清理 `componentDidMount` 的效果。 ```js {6-8} class ChatRoom extends Component { @@ -298,7 +298,7 @@ class ChatRoom extends Component { -对于大多数的使用场景来说,在类组件中一起定义 `componentDidMount`,`componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 +对于大多数的使用场景来说,在类式组件中一起定义 `componentDidMount`,`componentDidUpdate` 和 `componentWillUnmount` 等同于在函数式组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -308,9 +308,9 @@ class ChatRoom extends Component { ### `componentDidUpdate(prevProps, prevState, snapshot?)` {/*componentdidupdate*/} -如果你定义了 `componentDidUpdate` 方法,当你的组件更新了 props 或 state 重新渲染后,React 将立即调用它。这个方法不会在首次渲染时调用。 +如果你定义了 `componentDidUpdate` 方法,那么 React 会在你的组件更新了 props 或 state 重新渲染后立即调用它。这个方法不会在首次渲染时调用。 -你可以在更新后使用它来操作 DOM。这也是进行网络请求的常见位置,只要你将当前的 props 与以前的 props 进行比较即可(例如,如果 props 没有更改,则可能不需要网络请求)。一般来说,这个方法与 [`componentDidMount`](#componentdidmount) 以及 [`componentWillUnmount`](#componentwillunmount) 一起使用: +你可以在一次更新后使用它来操作 DOM。处理网络请求时也可能会使用这个方法,将当前的 props 与以前的 props 进行比较(例如,如果 props 没有更改,则可能不需要网络请求)。一般来说,这个方法与 [`componentDidMount`](#componentdidmount) 以及 [`componentWillUnmount`](#componentwillunmount) 一起使用: ```js {10-18} class ChatRoom extends Component { @@ -345,11 +345,11 @@ class ChatRoom extends Component { #### 参数 {/*componentdidupdate-parameters*/} -* `prevProps`:更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`:更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定发生了什么改变。 -* `prevState`:更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`:更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定发生了什么改变。 -* `snapshot`:如果你设置了 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 方法,那么 `snapshot` 将包含从该方法返回的值。否则它将是 `undefined`。 +* `snapshot`:如果你实现了 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 方法,那么 `snapshot` 将包含从该方法返回的值。否则它将是 `undefined`。 #### 返回值 {/*componentdidupdate-returns*/} @@ -357,15 +357,15 @@ class ChatRoom extends Component { #### 注意 {/*componentdidupdate-caveats*/} -- 如果你定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并且返回 `false` 的话,那么 `componentDidUpdate` 将不会被调用。 +- 如果你定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并且返回值是 `false` 的话,那么 `componentDidUpdate` 将不会被调用。 - `componentDidUpdate` 内部的逻辑通常应该包含在比较 `this.props` 与 `prevProps` 以及 `this.state` 与 `prevState` 之中。否则就会存在创建无限循环的风险。 -- 虽然可以在 `componentDidUpdate` 中立即调用 [`setState`](#setstate),但最好尽可能避免这样做。它将触发一个额外的渲染,但它是在浏览器更新屏幕之前发生的。这导致了即使 [`render`](#render) 在这种情况下会被调用两次,用户也看不到中间状态。这种模式通常会导致性能问题,但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 +- 虽然可以在 `componentDidUpdate` 中直接调用 [`setState`](#setstate),但最好尽可能避免这样做。因为它将触发一次额外的渲染,而且是在浏览器更新屏幕内容之前发生的。在这种情况下,即使 [`render`](#render) 会被调用两次,用户也看不到中间状态。这种模式通常会导致性能问题,但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 -对于大多数用例来说,在类组件中一起定义 `componentDidMount`,`componentDidUpdate` 和 `componentWillUnmount` 等同于在函数组件中定义 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 +对于大多数用例来说,在类式组件中一起定义 `componentDidMount`,`componentDidUpdate` 和 `componentWillUnmount` 等同于在函数式组件中定义 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -376,9 +376,9 @@ class ChatRoom extends Component { -此 API 已从 `componentWillMount` 重命名为 [`UNSAFE_componentWillMount`](#unsafe_componentwillmount)。旧名称已被弃用,在 React 未来主要的版本中,只有新名称才有效。 +此 API 已从 `componentWillMount` 重命名为 [`UNSAFE_componentWillMount`](#unsafe_componentwillmount)。旧名称已被弃用,在 React 未来的主版本中,只有新名称才有效。 -运行 [`rename-unsafe-lifecycles` 重构器](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 +运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -388,9 +388,9 @@ class ChatRoom extends Component { -此 API 已从 `componentWillReceiveProps` 重命名为 [`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops)。旧名称已被弃用,在 React 未来主要的版本中,只有新名称才有效。 +此 API 已从 `componentWillReceiveProps` 重命名为 [`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops)。旧名称已被弃用,在 React 未来的主版本中,只有新名称才有效。 -运行 [`rename-unsafe-lifecycles` 重构器](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 +运行 [`rename-unsafe-lifecycles` codemod](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -400,7 +400,7 @@ class ChatRoom extends Component { -此 API 已从 `componentWillUpdate` 重命名为 [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate)。旧名称已被弃用,在 React 的未来主要版本中,只有新名称才有效。 +此 API 已从 `componentWillUpdate` 重命名为 [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate)。旧名称已被弃用,在 React 未来的主版本中,只有新名称才有效。 运行 [`rename-unsafe-lifecycles` 重构器](https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles) 来自动更新你的组件。 @@ -410,9 +410,9 @@ class ChatRoom extends Component { ### `componentWillUnmount()` {/*componentwillunmount*/} -如果你定义了 `componentWillUnmount` 方法,React 会在你的组件被移除屏幕(**卸载**)之前调用它。这是取消数据获取或删除监听的常用位置。 +如果你定义了 `componentWillUnmount` 方法,React 会在你的组件被移除屏幕(**卸载**)之前调用它。此方法常常用于取消数据获取或移除监听事件。 -`componentWillUnmount` 内部的逻辑应该完全“对应”到 [`componentDidMount`](#componentdidmount) 内部的逻辑,例如,如果你在 `componentDidMount` 中设置了一个监听,那么 `componentWillUnmount` 中就应该清除掉这个监听。如果你的 `componentWillUnmount` 的清理逻辑中读取了一些 props 或者 state,那么你通常还需要实现一个 [`componentDidUpdate`](#componentdidupdate) 来清理使用了旧 props 和 state 的资源(例如监听)。 +`componentWillUnmount` 内部的逻辑应该完全“对应”到 [`componentDidMount`](#componentdidmount) 内部的逻辑,例如,如果你在 `componentDidMount` 中设置了一个监听事件,那么 `componentWillUnmount` 中就应该清除掉这个监听事件。如果你的 `componentWillUnmount` 的清理逻辑中读取了一些 props 或者 state,那么你通常还需要实现一个 [`componentDidUpdate`](#componentdidupdate) 来清理使用了旧 props 和 state 的资源(例如监听事件)。 ```js {20-22} class ChatRoom extends Component { @@ -454,11 +454,11 @@ class ChatRoom extends Component { #### 注意 {/*componentwillunmount-caveats*/} -- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发中 React 会调用 [`componentDidMount`](#componentdidmount) 然后立即调用 `componentWillUnmount`,接着再次调用 `componentDidMount`。这可以帮助你注意到你是否忘记实现 `componentWillUnmount`,或者它的逻辑是否没有完全对应到 `componentDidMount` 的效果。 +- 当 [严格模式](/reference/react/StrictMode) 开启时,在开发中 React 会在调用 [`componentDidMount`](#componentdidmount) 后立即调用 `componentWillUnmount`,接着再次调用 `componentDidMount`。这可以帮助你注意到你是否忘记实现 `componentWillUnmount`,或者它的逻辑是否没有完全对应到 `componentDidMount` 的效果。 -对于许多用例来说,在类组件中一起定义 `componentDidMount`、`componentDidUpdate` 和 `componentWillUnmount` 相当于在函数组件中调用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 +对于许多用例来说,在类式组件中一起定义 `componentDidMount`、`componentDidUpdate` 和 `componentWillUnmount` 等同于在函数式组件中使用 [`useEffect`](/reference/react/useEffect)。在一些少数的情况,例如在浏览器绘制前执行代码很重要时,更像是等同于 [`useLayoutEffect`](/reference/react/useLayoutEffect)。 [了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -470,13 +470,13 @@ class ChatRoom extends Component { 强制组件重新渲染。 -通常来说,这是没必要的。如果组件的 [`render`](#render) 方法仅读取了 [`this.props`](#props)、[`this.state`](#state) 或 [`this.context`]( #context) 时,当你在组件或其任一父组件内调用 [`setState`](#setstate) 时,它就将自动重新渲染。但是,如果组件的 `render` 方法是直接读取外部数据源时,则必须告诉 React 在该数据源更改时更新用户界面。这就是你可以用 `forceUpdate` 做的事。 +通常来说,这是没必要的。如果组件的 [`render`](#render) 方法仅读取了 [`this.props`](#props)、[`this.state`](#state) 或 [`this.context`]( #context) 时,当你在组件或其任一父组件内调用 [`setState`](#setstate) 时,它就将自动重新渲染。但是,如果组件的 `render` 方法是直接读取外部数据源时,则必须告诉 React 在该数据源更改时更新用户界面。这就是 `forceUpdate` 的作用。 -尽量避免使用 `forceUpdate` 并且在 `render` 中只读取 `this.props` 和 `this.state`。 +尽量避免使用 `forceUpdate` 并且在 `render` 中尽量只读取 `this.props` 和 `this.state`。 #### 参数 {/*forceupdate-parameters*/} -* **可选的** 如果指定了 `callback`,React 将在提交更新后调用你提供的 `callback`。 +* **可选的** 如果指定了 `callback`,React 将在提交完更新后调用你提供的 `callback`。 #### 返回值 {/*forceupdate-returns*/} @@ -488,7 +488,7 @@ class ChatRoom extends Component { -读取外部数据源并强制类组件使用 `forceUpdate` 来重新渲染更改已被函数组件中的 [`useSyncExternalStore`](/reference/react/useSyncExternalStore) 所取代。 +读取外部数据源并强制类式组件使用 `forceUpdate` 来重新渲染更改已被函数式组件中的 [`useSyncExternalStore`](/reference/react/useSyncExternalStore) 所取代。 @@ -498,17 +498,17 @@ class ChatRoom extends Component { -该 API 将在 React 未来主要的版本中删除。[使用 `Context.Provider` 代替](/reference/react/createContext#provider)。 +该 API 将在 React 未来的主版本中删除。[使用 `Context.Provider` 代替](/reference/react/createContext#provider)。 -允许你指定由该组件提供的 [过时的 context](https://reactjs.org/docs/legacy-context.html) 的值。 +允许你指定由该组件提供的 [非法的 context](https://reactjs.org/docs/legacy-context.html) 的值。 --- ### `getSnapshotBeforeUpdate(prevProps, prevState)` {/*getsnapshotbeforeupdate*/} -如果你实现了 `getSnapshotBeforeUpdate`,React 会在 React 更新 DOM 之前时立即调用它。它使你的组件能够在 DOM 发生更改之前捕获一些信息(例如滚动位置)。此生命周期方法返回的任何值都将作为参数传递给 [`componentDidUpdate`](#componentdidupdate)。 +如果你实现了 `getSnapshotBeforeUpdate`,React 会在 React 更新 DOM 之前时直接调用它。它使你的组件能够在 DOM 发生更改之前捕获一些信息(例如滚动的位置)。此生命周期方法返回的任何值都将作为参数传递给 [`componentDidUpdate`](#componentdidupdate)。 例如,你可以在像是需要在更新期间保留其滚动位置的聊天消息的 UI 中来使用它。 @@ -520,8 +520,8 @@ class ScrollingList extends React.Component { } getSnapshotBeforeUpdate(prevProps, prevState) { - // 我们是否要向列表中添加新项目? - // 捕获滚动​​位置,以便我们稍后可以调整滚动。 + // 我们是否要向列表中添加新内容? + // 捕获滚动的​​位置,以便我们稍后可以调整滚动。 if (prevProps.list.length < this.props.list.length) { const list = this.listRef.current; return list.scrollHeight - list.scrollTop; @@ -530,8 +530,8 @@ class ScrollingList extends React.Component { } componentDidUpdate(prevProps, prevState, snapshot) { - // 如果我们有快照值,那么我们刚刚添加了新项目。 - // 调整滚动,使这些新项目不会将旧项目推出视野。 + // 如果我们有快照值,那么说明我们刚刚添加了新内容。 + // 调整滚动,使得这些新内容不会将旧内容推出视野。 // (这里的 snapshot 是 getSnapshotBeforeUpdate 返回的值) if (snapshot !== null) { const list = this.listRef.current; @@ -547,13 +547,13 @@ class ScrollingList extends React.Component { } ``` -在上面的示例中,直接在 `getSnapshotBeforeUpdate` 中读取 `scrollHeight` 属性非常重要。在 [`render`](#render)、[`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops) 或 [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate) 中读取它是不安全的,因为在这些方法被调用和 React 更新 DOM 之间存在潜在的时间间隔。 +在上面的示例中,能直接在 `getSnapshotBeforeUpdate` 中读取到 `scrollHeight` 属性非常重要。在 [`render`](#render)、[`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops) 或 [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate) 中读取它是不安全的,因为这些方法被调用与 React 更新 DOM 之间存在潜在的时间间隔。 #### 参数 {/*getsnapshotbeforeupdate-parameters*/} -* `prevProps`:更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`:更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定发生了什么改变。 -* `prevState`:更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`:更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定发生了什么改变。 #### 返回值 {/*getsnapshotbeforeupdate-returns*/} @@ -565,7 +565,7 @@ class ScrollingList extends React.Component { -目前,函数组件中还没有与 `getSnapshotBeforeUpdate` 等同的方法。这种使用场景非常罕见,但如果你有这种需求,那么你就必须编写一个类组件。 +目前,函数式组件中还没有与 `getSnapshotBeforeUpdate` 等同的方法。这种使用场景非常罕见,但如果你有这种需求,那么你就必须编写一个类式组件。 @@ -573,7 +573,7 @@ class ScrollingList extends React.Component { ### `render()` {/*render*/} -`render` 方法是类组件中唯一必需的方法。 +`render` 方法是类式组件中唯一必需的方法。 `render` 方法应该指定你想要在屏幕上显示的内容,例如: @@ -587,15 +587,15 @@ class Greeting extends Component { } ``` -React 可能随时调用 `render`,因此你不应该假设它在特定时间运行。一般来说,`render` 方法应该返回一段 [JSX](/learn/writing-markup-with-jsx),但也支持一些 [其他的返回类型](#render-returns)(如字符串)。为了计算返回的 JSX,`render` 方法可以读取 [`this.props`](#props)、[`this.state`](#state) 和 [`this.context`](#context)。 +React 可能随时调用 `render` 方法,因此你不应该假设它将在某一特定时间运行。一般来说,`render` 方法应该返回一段 [JSX](/learn/writing-markup-with-jsx),但它也支持一些 [其他的返回类型](#render-returns)(如字符串)。为了计算返回的 JSX,`render` 方法可以读取 [`this.props`](#props)、[`this.state`](#state) 和 [`this.context`](#context)。 -你应该将 `render` 方法编写为纯函数,这意味着如果 props、state 和 context 相同,它应该返回相同的结果。它也不应该包含副作用(例如设置监听)或与浏览器 API 交互。副作用应该发生在事件处理程序或 [`componentDidMount`](#componentdidmount) 等方法中。 +你应该将 `render` 方法编写为纯函数,这意味着如果它使用的 props、state 和 context 相同的话,它应该返回相同的结果。它也不应该包含副作用(例如订阅监听事件)或与浏览器 API 交互。副作用应该发生在事件处理程序或 [`componentDidMount`](#componentdidmount) 等方法中。 #### 参数 {/*render-parameters*/} -* `prevProps`:更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定是否改变。 +* `prevProps`:更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定发生了什么改变。 -* `prevState`:更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定是否改变。 +* `prevState`:更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定发生了什么改变。 #### 返回值 {/*render-returns*/} @@ -609,7 +609,7 @@ React 可能随时调用 `render`,因此你不应该假设它在特定时间 - 当 [严格模式](/reference/react/StrictMode) 开启时,React 将在开发过程中调用两次 `render`,然后丢弃其中一个结果。这可以帮助你注意到需要从 `render` 方法中移出的意外的副作用。 -- `render` 调用和后续的 `componentDidMount` 或 `componentDidUpdate` 调用之间没有一一对应的关系。React 可能会在有益的情况下丢弃一些 `render` 的调用结果。 +- `render` 的调用和后续的 `componentDidMount` 或 `componentDidUpdate` 的调用之间没有一一对应的关系。React 可能会在有益的情况下丢弃一些 `render` 的调用结果。 --- @@ -641,11 +641,11 @@ class Form extends Component { } ``` -`setState` 将组件的 state 的更改加入队列。它告诉 React 该组件及其子组件需要使用新状态重新渲染。这是更新用户界面来响应交互的主要方式。 +`setState` 将组件的 state 的更改加入队列。它告诉 React 该组件及其子组件需要使用新的 state 来重新渲染。这是更新用户界面来响应交互的主要方式。 -调用 `setState` 时 **不会** 更改已执行代码中的当前 state: +调用 `setState` 时 **不会** 更改已执行代码中当前的 state: ```js {6} function handleClick() { @@ -679,9 +679,9 @@ function handleClick() { * `nextState`:一个对象或者函数。 * 如果你传递一个对象作为 `nextState`,它将浅层合并到 `this.state` 中。 - * 如果你传递一个函数作为 `nextState`,它将被视为 **更新函数**。它必须是个纯函数,应该以已加载的 state 和 props 作为参数,并且应该返回要浅层合并到 `this.state` 中的对象。React 会将你的更新函数放入队列中并重新渲染你的组件。在下一次渲染期间,React 将通过应用队列中的所有更新程序来计算下一个 state。 + * 如果你传递一个函数作为 `nextState`,它将被视为 **更新函数**。它必须是个纯函数,应该以已加载的 state 和 props 作为参数,并且应该返回要浅层合并到 `this.state` 中的对象。React 会将你的更新函数放入队列中并重新渲染你的组件。在下一次渲染期间,React 将通过应用队列中的所有的更新函数来计算下一个 state。 -* **可选的** `callback`:如果你指定,React 将在提交更新后调用你提供的`回调函数`。 +* **可选的** `callback`:如果你指定该函数,React 将在提交更新后调用你提供的 `callback`。 #### 返回值 {/*setstate-returns*/} @@ -689,13 +689,13 @@ function handleClick() { #### 注意 {/*setstate-caveats*/} -- 将 `setState` 视为 **请求**,而不是立即会更新组件的命令。当多个组件更新它们的 state 以响应事件时,React 将批量更新它们,并在这次事件结束时将它们一并重新渲染。在极少数情况下,你需要强制同步应用特定的状态更新,你可以将其包装在 [`flushSync`](/reference/react-dom/flushSync) 中,但这可能会损害性能。 +- 将 `setState` 视为 **请求** 而会不是立即更新组件的命令。当多个组件更新它们的 state 来响应事件时,React 将批量更新它们,并在这次事件结束时将它们一并重新渲染。在极少数情况下,你需要强制同步应用特定的 state 更新,这时你可以将其包装在 [`flushSync`](/reference/react-dom/flushSync) 中,但这可能会损害性能。 -- `setState` 不会立即更新 `this.state`。这让在调用 `setState` 之后立即读取 `setState` 成为一个潜在的陷阱。相反请使用 [`componentDidUpdate`](#componentdidupdate) 或设置 setState `callback` 参数,其中任何一个都保证读取在 state 更新后触发。如果需要根据前一个 state 来设置 state,可以将函数传递给 `nextState`,如上所述。 +- `setState` 不会立即更新 `this.state`。这让在调用 `setState` 之后立即读取 `setState` 成为了一个潜在的陷阱。相反请使用 [`componentDidUpdate`](#componentdidupdate) 或设置 setState的 `callback` 参数,其中任何一个都保证读取 state 将在 state 的更新后触发。如果需要根据前一个 state 来设置 state,那么可以传递给 `nextState` 一个函数,如上所述。 -在类组件中调用 `setState` 等同于在函数组件中调用 [`set` 函数](/reference/react/useState#setstate)。 +在类式组件中调用 `setState` 等同于在函数式组件中调用 [`set` 函数](/reference/react/useState#setstate)。 [了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function)。 @@ -744,7 +744,7 @@ class Rectangle extends Component { #### 返回值 {/*shouldcomponentupdate-returns*/} -如果你希望组件重新渲染的话,返回 `true`。这是也是默认执行的操作。 +如果你希望组件重新渲染的话就返回 `true`。这是也是默认执行的操作。 返回 `false` 来告诉 React 可以跳过重新渲染。 @@ -752,17 +752,17 @@ class Rectangle extends Component { - 此方法 **仅仅** 作为性能优化而存在。如果你的组件在没有它的情况下损坏,请先修复组件。 -- 可以考虑使用 [`PureComponent`](/reference/react/PureComponent) 而不是手写 `shouldComponentUpdate`。`PureComponent` 浅比较 props 和 state,这样可以减少错过必要更新的概率。 +- 可以考虑使用 [`PureComponent`](/reference/react/PureComponent) 而不是手写 `shouldComponentUpdate`。`PureComponent` 会浅比较 props 和 state 以及减少错过必要更新的概率。 -- 我们不建议在 `shouldComponentUpdate` 中进行深度相等检查或使用 `JSON.stringify`。因为它使性能变得不可预测并且它与每个 prop 和 state 的数据结构有关。在最好的情况下,你可能会面临给应用程序引入多秒停顿的风险,而在最坏的情况下,你可能会面临使应用程序崩溃的风险。 +- 我们不建议在 `shouldComponentUpdate` 中使用深度相等检查或使用 `JSON.stringify`。因为它使性能变得不可预测并且它与每个 prop 和 state 的数据结构有关。在最好的情况下,你可能会面临给应用程序引入多秒停顿的风险,而在最坏的情况下,你可能会面临使应用程序崩溃的风险。 - 返回 `false` 并不会阻止子组件在 **他们的** state 发生变化时重新渲染。 -- 返回 `false` 并不能 **确保** 组件不会重新渲染。React 将使用返回值作为提示,但如果出于其他有意义原因,它仍然可能选择重新渲染你的组件。 +- 返回 `false` 并不能 **确保** 组件不会重新渲染。React 将使用返回值作为提示,但如果是出于其他有意义的原因,它仍然可能选择重新渲染你的组件。 -使用 `shouldComponentUpdate` 来优化类组件与使用 [`memo`](/reference/react/memo) 来优化函数组件类似。函数组件还使用 [`useMemo`](/reference/react/useMemo) 来提供更精细的优化。 +使用 `shouldComponentUpdate` 来优化类式组件与使用 [`memo`](/reference/react/memo) 来优化函数式组件类似。函数式组件还使用 [`useMemo`](/reference/react/useMemo) 来提供更精细的优化。 @@ -770,10 +770,10 @@ class Rectangle extends Component { ### `UNSAFE_componentWillMount()` {/*unsafe_componentwillmount*/} -如果你定义了 `UNSAFE_componentWillMount`,React 会在 [`constructor`](#constructor) 之后立即调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反请使用其他替代方案: +如果你定义了 `UNSAFE_componentWillMount`,React 会在 [`constructor`](#constructor) 之后就立即调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反请使用其他替代方案: - 要初始化状态,请将 [`state`](#state) 声明为类字段或在 [`constructor`](#constructor) 内设置 `this.state`。 -- 如果你需要运行额外作用或设置监听,请将该逻辑移至 [`componentDidMount`](#componentdidmount)。 +- 如果你需要运行额外作用或订阅监听事件事件,请将该逻辑移至 [`componentDidMount`](#componentdidmount)。 [查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples)。 @@ -789,13 +789,13 @@ class Rectangle extends Component { - 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillMount`。 -- 即使它的名字是这样的,但是如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等新式的 React 功能时,`UNSAFE_componentWillMount` 不保证组件 **将** 被挂载。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),那么 React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。这就是为什么这种方法是 **不安全** 的。依赖于挂载(例如添加监听)的代码应放入 [`componentDidMount`](#componentdidmount)。 +- 尽管它的名字是这样的,但是如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等新式的 React 功能时,`UNSAFE_componentWillMount` 不保证组件 **将** 被挂载。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),那么 React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。这就是为什么这种方法是 **不安全** 的。依赖于挂载(例如添加监听事件)的代码应放入 [`componentDidMount`](#componentdidmount)。 -- `UNSAFE_componentWillMount` 是运行 [服务器渲染](/reference/react-dom/server) 期间运行的唯一生命周期方法。对于所有实际用途来说,它与 [`constructor`](#constructor) 相同,因此你应该使用 `constructor` 来代替这种类型的逻辑。 +- `UNSAFE_componentWillMount` 是运行 [服务器渲染](/reference/react-dom/server) 期间运行的唯一生命周期方法。对于所有实际上的用途来说,它与 [`constructor`](#constructor) 相同,因此你应该使用 `constructor` 来代替这种类型的逻辑。 -在类组件中的 `UNSAFE_componentWillMount` 内部调用 [`setState`](#setstate) 来初始化状态等同于函数组件中用该 state 作为初始 state 传递给 [`useState`]。 +在类式组件中的 `UNSAFE_componentWillMount` 内部调用 [`setState`](#setstate) 来初始化状态等同于函数式组件中用该 state 作为初始 state 传递给 [`useState`]。 @@ -805,10 +805,10 @@ class Rectangle extends Component { 如果你定义了 `UNSAFE_componentWillReceiveProps`,React 会在组件收到新的 props 时调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反请使用以下替代方案: -- 如果你需要 **运行额外作用**(例如,获取数据、运行动画或重新初始化监听)来响应 prop 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate)。 -- 如果你需要 **避免仅在 prop 更改时重新计算某些数据** 时,请使用 [memoization helper](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization) 来代替。 -- 如果你需要 **在 prop 更改时`重置`某些状态** 时,请考虑使组件 [完全控制](https://legacy.reactjs.org/blog/2018/06/07/you-probously-不需要派生状态。html#recommendation-fully-controlled-component) 或者 [使用 key 使组件完全不受控](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) 来代替。 -- 如果你需要 **在 prop 更改时`调整`某些状态,** 检查你是否可以在渲染期间单独从 props 计算所有必要的信息。如果不能,请使用 [`static getDerivedStateFromProps`](/reference/react/Component#static-getdrivenstatefromprops) 代替。 +- 如果你需要 **运行副作用**(例如,获取数据、运行动画或重新初始化监听)来响应 prop 的更改,那么请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate)。 +- 如果你需要 **避免仅 prop 更改时就重新计算某些数据** 时,请使用 [memoization helper](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization) 来代替。 +- 如果你需要 **在 prop 更改时“重置”某些状态** 时,请考虑使组件 [完全控制](https://legacy.reactjs.org/blog/2018/06/07/you-probously-不需要派生状态。html#recommendation-fully-controlled-component) 或者 [使用 key 使组件完全不受控](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key) 来代替。 +- 如果你需要 **在 prop 更改时“调整”某些状态** 时,请检查你是否可以在渲染期间单独从 props 计算所有必要的信息。如果不能,请使用 [`static getDerivedStateFromProps`](/reference/react/Component#static-getdrivenstatefromprops) 代替。 [查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props)。 @@ -825,7 +825,7 @@ class Rectangle extends Component { - 如果组件实现了 [`static getDerivedStateFromProps`](#static-getdrivenstatefromprops) 或 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate),则不会调用 `UNSAFE_componentWillReceiveProps`。 -- 即使它的名字是这样的,但如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等新式的 React 功能时,`UNSAFE_componentWillReceiveProps` 不保证组件 **将会** 接收这些 Props。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,Props 可能会有所不同。这就是为什么这种方法 **不安全**。仅为更新(例如重置监听)的代码应放入 [`componentDidUpdate`](#componentdidupdate)。 +- 尽管它的名字是这样的,但如果你的应用程序使用 [`Suspense`](/reference/react/Sus​​pense) 等新式的 React 功能时,`UNSAFE_componentWillReceiveProps` 不保证组件 **将会** 接收这些 Props。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,Props 可能会有所不同。这就是为什么这种方法 **不安全**。仅为了提交更新(例如重置监听事件)的代码应放入 [`componentDidUpdate`](#componentdidupdate)。 - `UNSAFE_componentWillReceiveProps` 并不意味着组件收到了与上次 **不同的** props。你需要自己比较 `nextProps` 和 `this.props` 以检查是否发生了变化。 @@ -833,7 +833,7 @@ class Rectangle extends Component { -在类组件中的 `UNSAFE_componentWillReceiveProps` 里调用 [`setState`](#setstate) 来“调整”state 等同于在函数组件在 [渲染期间从 `useState` 调用 `set` 函数](/reference/react/useState#storing-information-from-previous-renders)。 +在类式组件中的 `UNSAFE_componentWillReceiveProps` 里调用 [`setState`](#setstate) 来“调整”state 等同于在函数式组件在 [渲染期间从 `useState` 调用 `set` 函数](/reference/react/useState#storing-information-from-previous-renders)。 @@ -844,8 +844,8 @@ class Rectangle extends Component { 如果你定义了 `UNSAFE_componentWillUpdate`,React 会在使用新的 props 或 state 渲染之前调用它。它仅因历史原因而存在,不应在任何新代码中使用。相反请使用下面的替代方案: -- 如果你需要运行额外作用(例如,获取数据、运行动画或重新初始化监听)来响应 prop 或 state 更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate)。 -- 如果需要从 DOM 中读取一些信息(例如,保存当前滚动位置)以便稍后在 [`componentDidUpdate`](#componentdidupdate) 中使用的话,那么请在 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 中读取。 +- 如果你需要运行副作用(例如,获取数据、运行动画或重新初始化监听)来响应 prop 或 state 的更改,请将该逻辑移至 [`componentDidUpdate`](#componentdidupdate)。 +- 如果需要从 DOM 中读取一些信息(例如,保存当前滚动位置)以便稍后在 [`componentDidUpdate`](#componentdidupdate) 中使用的话,那么请在 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 中读取这些信息。 [查看避免不安全生命周期的示例](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html#examples)。 @@ -866,7 +866,7 @@ class Rectangle extends Component { - 不支持在 `componentWillUpdate` 期间调用 [`setState`](#setstate)(或任何导致调用 `setState` 的方法,例如调度 Redux 操作)。 -- 尽管它的命名是这样,但如果你的应用程序使用如 [`Suspense`](/reference/react/Sus​​pense) 时等新式的 React 功能时,`UNSAFE_componentWillUpdate` 并不能保证组件 **将会** 更新。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,props 和 state 可能会有所不同。这就是为什么这种方法“不安全”。仅针对更新(例如重置监听)运行的代码应放入 [`componentDidUpdate`](#componentdidupdate)。 +- 尽管它的命名是这样,但如果你的应用程序使用如 [`Suspense`](/reference/react/Sus​​pense) 时等新式的 React 功能时,`UNSAFE_componentWillUpdate` 并不能保证组件 **将会** 更新。如果渲染尝试被中止(例如,因为某些子组件的代码尚未加载),React 将丢弃正在进行的树,并在下一次尝试期间尝试从头开始构建组件。到下一次渲染尝试时,props 和 state 可能会有所不同。这就是为什么这种方法“不安全”。仅针对提交更新(例如重置监听)而运行的代码应放入 [`componentDidUpdate`](#componentdidupdate)。 - `UNSAFE_componentWillUpdate` 并不意味着组件收到了与上次不同的 props 或 state。你需要自己将 `nextProps` 与 `this.props` 以及 `nextState` 与 `this.state` 进行比较,以检查是否发生了变化。 @@ -874,7 +874,7 @@ class Rectangle extends Component { -函数组件中没有与 `UNSAFE_componentWillUpdate` 直接等同的方法。 +函数式组件中没有与 `UNSAFE_componentWillUpdate` 直接等同的方法。 @@ -884,7 +884,7 @@ class Rectangle extends Component { -该 API 将在 React 未来主要的版本中删除。[使用 `static contextType` 代替](#static-contexttype)。 +该 API 将在 React 未来的主版本中删除。[使用 `static contextType` 代替](#static-contexttype)。 @@ -906,7 +906,7 @@ class Rectangle extends Component { ### `static contextType` {/*static-contexttype*/} -如果你想从类组件中读取 [`this.context`](#context-instance-field),则必须指定它需要读取哪个 context。你指定为 `static contextType` 的 context 必须是之前由 [`createContext` 创建的值](/reference/react/createContext)。 +如果你想从类式组件中读取 [`this.context`](#context-instance-field),则必须指定它需要读取哪个 context。你指定为 `static contextType` 的 context 必须是之前由 [`createContext` 创建的值](/reference/react/createContext)。 ```js {2} class Button extends Component { @@ -926,7 +926,7 @@ class Button extends Component { -在类组件中读取 `this.context` 等同于在函数组件中读取 [`useContext`](/reference/react/useContext)。 +在类式组件中读取 `this.context` 等同于在函数式组件中读取 [`useContext`](/reference/react/useContext)。 [了解如何迁移](#migrating-a-component-with-context-from-a-class-to-a-function)。 @@ -972,7 +972,7 @@ class Button extends Component { -在类组件中定义 `defaultProps` 类似于在函数组件中使用 [默认值](/learn/passing-props-to-a-component#specifying-a-default-value-for-a-prop)。 +在类式组件中定义 `defaultProps` 类似于在函数式组件中使用 [默认值](/learn/passing-props-to-a-component#specifying-a-default-value-for-a-prop)。 @@ -1016,7 +1016,7 @@ class Greeting extends React.Component { #### 参数 {/*static-getderivedstatefromerror-parameters*/} -* `error`:被抛出的错误。实际上,它通常是 [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,但这并不能保证,因为 JavaScript 允许 [`抛出`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw) 任何类型的值,包括字符串甚至是 `null`。 +* `error`:被抛出的错误。实际上,它通常是 [`Error`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,但这并不能保证,因为 JavaScript 允许 [`抛出`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/throw) 任何类型的值,包括字符串甚至是 `null`。 #### 返回值 {/*static-getderivedstatefromerror-returns*/} @@ -1024,11 +1024,11 @@ class Greeting extends React.Component { #### 注意 {/*static-getderivedstatefromerror-caveats*/} -* `static getDerivedStateFromError` 应该是一个纯函数。如果你想执行额外作用(例如调用分析服务),你还需要实现 [`componentDidCatch`](#componentdidcatch)。 +* `static getDerivedStateFromError` 应该是一个纯函数。如果你想执行副作用(例如调用分析服务),你还需要实现 [`componentDidCatch`](#componentdidcatch)。 -函数组件中目前还没有与 `static getDerivedStateFromError` 直接等同的东西。如果你想避免创建类组件,请像上面那样编写一个 `ErrorBoundary` 组件,并在整个应用程序中使用它。或者使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包来执行此操作。 +函数式组件中目前还没有与 `static getDerivedStateFromError` 直接等同的东西。如果你想避免创建类式组件,请像上面那样编写一个 `ErrorBoundary` 组件,并在整个应用程序中使用它。或者使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包来执行此操作。 @@ -1036,8 +1036,8 @@ class Greeting extends React.Component { ### `static getDerivedStateFromProps(props, state)` {/*static-getderivedstatefromprops*/} -如果你定义了 `static getDerivedStateFromProps`,React 会在初始挂载和后续更新调用 [`render`](#render) 的之前调用它。它应该返回一个对象来更新 state,或者返回 `null` 不更新任何内容。 - +如果你定义了 `static getDerivedStateFromProps`,React 会在初始挂载和后续更新调用 [`render`](#render) 的之前调用它。它应该返回一个对象来更新 state,或者返回 `null` 就不更新任何内容。 + 此方法适用于 [少数罕见用例](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state),其中 state 取决于 props 随着时间的推移的变化。例如,当 `userID` 属性更改时,此 `Form` 组件会重置 `email` 状态: ```js {7-18} @@ -1087,13 +1087,13 @@ class Form extends Component { #### 注意 {/*static-getderivedstatefromprops-caveats*/} -- 无论什么原因,此方法都会在 **每次** 渲染前触发。这与 [`UNSAFE_componentWillReceiveProps`](#unsafe_cmoponentwillreceiveprops) 不同,后者仅在父组件重新渲染时触发,而不是在内部调用 `setState` 时。 +- 无论什么原因,此方法都会在 **每次** 渲染时触发。这与 [`UNSAFE_componentWillReceiveProps`](#unsafe_cmoponentwillreceiveprops) 不同,后者仅在父组件不是因为调用了本地的 `setState` 而重新渲染时触发。 -- 此方法无权访问组件实例。如果你愿意,您可以在 `static getDerivedStateFromProps` 和其他类方法之间重用一些代码,也就是通过提取类定义之外的组件 props 和 state 的纯函数。 +- 此方法无权访问组件实例。如果你愿意,您可以在 `static getDerivedStateFromProps` 和其他类方法之间重用一些代码,也就是提取类定义之外的组件 props 和 state 的纯函数。 -在类组件中实现 `static getDerivedStateFromProps` 等同于在函数组件中 [在渲染期间从 useState 调用 set 函数](/reference/react/useState#storing-information-from-previous-renders)。 +在类式组件中实现 `static getDerivedStateFromProps` 等同于在函数式组件中 [在渲染期间从 useState 调用 set 函数](/reference/react/useState#storing-information-from-previous-renders)。 @@ -1101,7 +1101,7 @@ class Form extends Component { ## 用法 {/*usage*/} -### 定义类组件 {/*defining-a-class-component*/} +### 定义类式组件 {/*defining-a-class-component*/} 要将 React 组件定义为类,请扩展内置的 `Component` 类并定义 [`render` 方法](#render): @@ -1110,14 +1110,14 @@ import { Component } from 'react'; class Greeting extends Component { render() { - return

Hello, {this.props.name}!

; + return

你好, {this.props.name}!

; } } ``` 每当 React 需要确定屏幕上显示的内容时,它就会调用你的 [`render`](#render) 方法。一般来说,你会让它返回一些 [JSX](/learn/writing-markup-with-jsx)。你的 `render` 方法应该是一个 [纯函数](https://en.wikipedia.org/wiki/Pure_function):它应该只计算 JSX。 -与 [函数组件](/learn/your-first-component#defining-a-component) 类似,类组件可以从它的父组件 [通过 props 接收信息](/learn/your-first-component#defining-a-component)。然而,读取 props 的语法是不同的。例如,如果父组件渲染 ``,那么你可以从 [`this.props`](#props) 读取 `name` 属性,例如 `this.props.name`: +与 [函数式组件](/learn/your-first-component#defining-a-component) 类似,类式组件可以从它的父组件 [通过 props 接收信息](/learn/your-first-component#defining-a-component)。然而,读取 props 的语法是不同的。例如,如果父组件渲染了 `` 组件,那么你可以从 [`this.props`](#props) 读取 `name` 属性,例如 `this.props.name`: @@ -1126,7 +1126,7 @@ import { Component } from 'react'; class Greeting extends Component { render() { - return

Hello, {this.props.name}!

; + return

你好, {this.props.name}!

; } } @@ -1143,19 +1143,19 @@ export default function App() {
-请注意,类组件内部不支持 Hook 函数(以 `use` 开头的函数,例如 [`useState`](/reference/react/useState) )。 +请注意,类式组件内部不支持 Hook 函数(以 `use` 开头的函数,例如 [`useState`](/reference/react/useState))。 -我们建议使用函数组件,而不是类组件。[了解如何迁移](#migrating-a-simple-component-from-a-class-to-a-function)。 +我们建议使用函数式组件,而不是类式组件。[了解如何迁移](#migrating-a-simple-component-from-a-class-to-a-function)。 --- -### 向类组件添加 state {/*adding-state-to-a-class-component*/} +### 向类式组件添加 state {/*adding-state-to-a-class-component*/} -为了向类组件添加 [state](/learn/state-a-components-memory),请将一个对象分配给一个名为 [`state`](#state) 的属性。要更新 state 的话,请调用 [`this.setState`](#setstate)。 +为了向类式组件添加 [state](/learn/state-a-components-memory),请将一个对象分配给一个名为 [`state`](#state) 的属性。要更新 state 的话,请调用 [`this.setState`](#setstate)。 @@ -1205,13 +1205,13 @@ button { display: block; margin-top: 10px; } -我们建议使用函数组件,而不是类组件。[了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function)。 +我们建议使用函数式组件,而不是类式组件。[了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function)。 --- -### 向类组件中添加生命周期方法 {/*adding-lifecycle-methods-to-a-class-component*/} +### 向类式组件中添加生命周期方法 {/*adding-lifecycle-methods-to-a-class-component*/} 你可以在类中定义一些特殊方法。 @@ -1233,18 +1233,18 @@ export default function App() { return ( <> {show &&
} {show && } @@ -1307,7 +1307,7 @@ export default class ChatRoom extends Component { }} /> -

Welcome to the {this.props.roomId} room!

+

欢迎来到 {this.props.roomId} 聊天室!

); } @@ -1319,10 +1319,10 @@ export function createConnection(serverUrl, roomId) { // 真正的实现将实际地连接到服务器 return { connect() { - console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); + console.log('✅ 成功连接到 "' + roomId + '" 号聊天室,服务端 Url:' + serverUrl + '...'); }, disconnect() { - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl); + console.log('❌ 无法连接到 "' + roomId + '" 号聊天室,服务端 Url:' + serverUrl); } }; } @@ -1339,7 +1339,7 @@ button { margin-left: 10px; } -我们建议使用函数组件,而不是类组件。[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 +我们建议使用函数式组件,而不是类式组件。[了解如何迁移](#migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function)。 @@ -1347,9 +1347,9 @@ button { margin-left: 10px; } ### 使用错误边界捕获渲染错误 {/*catching-rendering-errors-with-an-error-boundary*/} -默认情况下,如果你的应用程序在渲染过程中抛出错误,React 将从屏幕上删除其 UI。为了防止这种情况,你可以将 UI 的一部分包装到 **错误边界** 中。错误边界是一个特殊的组件,可让你显示一些备用 UI,而不是例如错误消息这样崩溃的部分。 +默认情况下,如果你的应用程序在渲染过程中抛出错误,React 将从屏幕上删除其 UI。为了防止这种情况,你可以将 UI 的一部分包装到 **错误边界** 中。错误边界是一个特殊的组件,可让你显示一些备用 UI,而不是显示例如错误消息这样崩溃的部分。 -要实现错误边界组件,你需要提供 [`static getDerivedStateFromError`](#static-getderivedstatefromerror),它允许你更新状态以响应错误并向用户显示错误消息。你还可以选择实现 [`componentDidCatch`](#componentdidcatch) 来添加一些额外的逻辑,例如将错误记录到分析服务。 +要实现错误边界组件,你需要提供 [`static getDerivedStateFromError`](#static-getderivedstatefromerror),它允许你更新状态以响应错误并向用户显示错误消息。你还可以选择实现 [`componentDidCatch`](#componentdidcatch) 来添加一些额外的逻辑,例如将错误添加到分析服务。 ```js {7-10,12-19} class ErrorBoundary extends React.Component { @@ -1397,7 +1397,7 @@ class ErrorBoundary extends React.Component { -目前还没有办法将错误边界编写为函数组件。但是你不必自己编写错误边界类。例如,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包来代替。 +目前还没有办法将错误边界编写为函数式组件。但是你不必自己编写错误边界类。例如,你可以使用 [`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) 包来代替。 @@ -1405,11 +1405,11 @@ class ErrorBoundary extends React.Component { ## 备选方案 {/*alternatives*/} -### 将简单的类组件迁移为函数式 {/*migrating-a-simple-component-from-a-class-to-a-function*/} +### 将简单的类式组件迁移为函数式 {/*migrating-a-simple-component-from-a-class-to-a-function*/} -一般来说,你会把 [组件定义为函数](/learn/your-first-component#defining-a-component)。 +一般来说,你应该把 [组件定义为函数](/learn/your-first-component#defining-a-component)。 -例如,假设你要将 `Greeting` 从类组件转换为函数: +例如,假设你要将 `Greeting` 从类式组件转换为函数: @@ -1475,9 +1475,9 @@ export default function App() { --- -### 将具有 state 的类组件迁移到函数 {/*migrating-a-component-with-state-from-a-class-to-a-function*/} +### 将具有 state 的类式组件迁移到函数 {/*migrating-a-component-with-state-from-a-class-to-a-function*/} -假设你要将这个 `Counter` 从类组件转换为函数: +假设你要将这个 `Counter` 从类式组件转换为函数: @@ -1599,7 +1599,7 @@ button { display: block; margin-top: 10px; } ### 将具有生命周期方法的组件从类迁移到函数 {/*migrating-a-component-with-lifecycle-methods-from-a-class-to-a-function*/} -假设你要将具有生命周期方法的 `ChatRoom` 类组件转换为函数: +假设你要将具有生命周期方法的 `ChatRoom` 类式组件转换为函数: @@ -1687,7 +1687,7 @@ export default class ChatRoom extends Component { }} /> -

Welcome to the {this.props.roomId} room!

+

欢迎俩到 {this.props.roomId} 聊天室!

); } @@ -1699,10 +1699,10 @@ export function createConnection(serverUrl, roomId) { // 真正的实现将实际连接到服务器 return { connect() { - console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); + console.log('✅ 成功连接到 "' + roomId + '" 号聊天室,服务端 Url:' + serverUrl + '...'); }, disconnect() { - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl); + console.log('❌ 无法连接到 "' + roomId + '" 号聊天室,服务端 Url:' + serverUrl); } }; } @@ -1717,9 +1717,9 @@ button { margin-left: 10px; } 首先,验证你的 [`componentWillUnmount`](#componentwillunmount) 是否与 [`componentDidMount`](#componentdidmount) 执行相反的操作。在上面的示例中操作是正确的:它会断开 `componentDidMount` 设置的连接。如果缺少这样的逻辑,请先添加它。 -接下来,验证你的 [`componentDidUpdate`](#componentdidupdate) 方法是否可以处理对 `componentDidMount` 中使用的任何 props 和 state 的更改。在上面的例子中,`componentDidMount` 调用 `setupConnection` 来读取 `this.state.serverUrl` 和 `this.props.roomId`。这就是为什么 `componentDidUpdate` 检查 `this.state.serverUrl` 和 `this.props.roomId` 是否已更改,如果更改了则重置连接。如果你的 `componentDidUpdate` 逻辑丢失或无法处理所有相关 props 和 state 的更改,请首先修复该问题。 +接下来,验证你的 [`componentDidUpdate`](#componentdidupdate) 方法是否可以处理对 `componentDidMount` 中使用的任何 props 和 state 的更改。在上面的例子中,`componentDidMount` 调用 `setupConnection` 来读取 `this.state.serverUrl` 和 `this.props.roomId`。这就是为什么 `componentDidUpdate` 检查 `this.state.serverUrl` 和 `this.props.roomId` 是否已更改,如果更改了则重置连接。如果你的 `componentDidUpdate` 逻辑丢失或无法处理所有相关 props 和 state 的更改,那么请首先修复该问题。 -在上面的示例中,生命周期方法内的逻辑将组件连接到 React 外部的系统(聊天服务器)。要将组件连接到外部系统,[请将此逻辑描述为单个效果](/reference/react/useEffect#connecting-to-an-external-system): +在上面的示例中,生命周期方法内的逻辑将组件连接到 React 外部的系统(聊天服务器)。要将组件连接到外部系统,[请将此逻辑描述为单个 Effect](/reference/react/useEffect#connecting-to-an-external-system): ```js {6-12} import { useState, useEffect } from 'react'; @@ -1739,7 +1739,7 @@ function ChatRoom({ roomId }) { } ``` -这个 [`useEffect`](/reference/react/useEffect) 的调用就相当于实现了上面所有生命周期方法中的逻辑。如果你的生命周期方法做了多个互不相关的事,[将它们分成多个独立的效果](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things)。这是一个你可以使用的完整示例: +这个 [`useEffect`](/reference/react/useEffect) 的调用就相当于实现了上面所有生命周期方法中的逻辑。如果你的生命周期方法做了多个互不相关的事,[将它们分成多个独立的 Effect](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things)。这是一个你可以使用的完整示例: @@ -1808,10 +1808,10 @@ export function createConnection(serverUrl, roomId) { // 真正的实现将实际连接到服务器 return { connect() { - console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); + console.log('✅ 成功连接到 "' + roomId + '" 号聊天室,服务端 Url:' + serverUrl + '...'); }, disconnect() { - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl); + console.log('❌ 无法连接到 "' + roomId + '" 号聊天室,服务端 Url:' + serverUrl); } }; } @@ -1834,7 +1834,7 @@ button { margin-left: 10px; } ### 将具有 context 的组件从类迁移到函数 {/*migrating-a-component-with-context-from-a-class-to-a-function*/} -在这个例子中,`Panel` 和 `Button` 类组件从 [`this.context`](#context) 读取 [context](/learn/passing-data-deeply-with-context): +在这个例子中,`Panel` 和 `Button` 类式组件从 [`this.context`](#context) 读取 [context](/learn/passing-data-deeply-with-context): @@ -1875,8 +1875,8 @@ class Button extends Component { function Form() { return ( - - + + ); } @@ -1928,7 +1928,7 @@ export default function MyApp() { -当你将它们转换为函数组件时,将 `this.context` 用调用 [`useContext`](/reference/react/useContext) 来替换: +当你将它们转换为函数式组件时,将 `this.context` 用调用 [`useContext`](/reference/react/useContext) 来替换: @@ -1961,8 +1961,8 @@ function Button({ children }) { function Form() { return ( - - + + ); } From b523e832486d1329c56dc76dfeea1b0a6760a47b Mon Sep 17 00:00:00 2001 From: Tosuke <1848228664@qq.com> Date: Thu, 20 Jul 2023 20:56:58 +0800 Subject: [PATCH 10/13] fix most error --- src/content/reference/react/Component.md | 86 ++++++++++++------------ 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index 6fe663ada1..651daa8810 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -44,15 +44,15 @@ class Greeting extends Component { 只有 `render` 方法是必要的,其他方法是可选的。 -[参加下方更多示例](#usage)。 +[参见下方更多示例](#usage)。 --- ### `context` {/*context*/} -可以通过使用 `this.context` 来访问一个类式组件的 [context](/learn/passing-data-deeply-with-context)。只有当你使用 [`static contextType`](#static-contexttype) (最新的)或者 [`static contextTypes`](#static-contexttypes) (已被废弃的)来特别指定你想要接受 **哪一个** context 时它才会有效。 +可以通过使用 `this.context` 来访问一个类式组件的 [context](/learn/passing-data-deeply-with-context)。只有当你使用 [`static contextType`](#static-contexttype)(最新的)或者 [`static contextTypes`](#static-contexttypes)(已被废弃的)来特别指定你想要接受 **哪一个** context 时它才会有效。 -类式组件一次只能读取一个context。 +类式组件一次只能读取一个 context。 ```js {2,5} class Button extends Component { @@ -73,7 +73,7 @@ class Button extends Component { -在类式组件中读取 `this.context` 等同于在函数式组件中使用的 [`useContext`](/reference/react/useContext)。 +在类式组件中读取 `this.context` 等同于在函数式组件中使用 [`useContext`](/reference/react/useContext)。 [了解如何迁移](#migrating-a-component-with-context-from-a-class-to-a-function)。 @@ -97,7 +97,7 @@ class Greeting extends Component { -在类式组件中读取 `this.props` 等同于在函数式组件中使用的 [声明式 props](/learn/passing-props-to-a-component#step-2-read-props-inside-the-child-component)。 +在类式组件中读取 `this.props` 等同于在函数式组件中使用 [声明式 props](/learn/passing-props-to-a-component#step-2-read-props-inside-the-child-component)。 [了解如何迁移](#migrating-a-simple-component-from-a-class-to-a-function)。 @@ -113,7 +113,7 @@ class Greeting extends Component {
-允许你获取此组件的 [非法字符串 ref](https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs) +允许你获取此组件的 [历史用法的字符串 ref](https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs)。 --- @@ -148,7 +148,7 @@ class Counter extends Component { -在类式组件中定义 `state` 等同于在函数式组件中通过调用 [`useState`](/reference/react/useState) 函数所创造的 state。 +在类式组件中定义 `state` 等同于在函数式组件中调用 [`useState`](/reference/react/useState)。 [了解如何迁移](#migrating-a-component-with-state-from-a-class-to-a-function)。 @@ -173,7 +173,7 @@ class Counter extends Component { } ``` -如果你使用较新的 JavaScript 语法的话,那么很少需要使用到 constructors。现代浏览器和像 [Babel](https://babeljs.io/) 这样的工具都支持的 [公有类字段语法](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/Public_class_fields),你可以使用它们来重写上面的代码。 +如果你使用较新的 JavaScript 语法的话,那么很少需要使用到 constructors。相反,你可以使用现代浏览器和像 [Babel](https://babeljs.io/) 这样的工具都支持的 [公有类字段语法](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/Public_class_fields) 来重写上面的代码: ```js {2,4} class Counter extends Component { @@ -184,7 +184,7 @@ class Counter extends Component { } ``` -constructor 不应该包含任何副作用或者监听相关的代码。 +构造函数不应包含任何存在副作用或者事件监听相关的代码。 #### 参数 {/*constructor-parameters*/} @@ -196,19 +196,19 @@ constructor 不应该包含任何副作用或者监听相关的代码。 #### 注意 {/*constructor-caveats*/} -* 不要在 constructor 中运行任何任额外作用或者监听相关的代码。使用 [`componentDidMount`](#componentdidmount) 来应对这种需求。 +* 不要在 constructor 中运行任何副作用或者监听相关的代码。使用 [`componentDidMount`](#componentdidmount) 来应对这种需求。 -* 在 constructor 中,你需要在其他声明之前调用 `super(props)`。如果你不这样做,`this.props` 在 constructor 运行时就会是 `undefined`,这可能会造成困惑并且导致错误。 +* 在 constructor 中,你需要在其他的声明之前调用 `super(props)`。如果你不这样做,`this.props` 在 constructor 运行时就会为 `undefined`,这可能会造成困惑并且导致错误。 -* Constructor 是唯一一个你能直接赋值 [`this.state`](#state) 的地方。在其余所有方法中,你需要使用 [`this.setState()`](#setstate) 来代替。不要使用在 constructor 中使用 `setState`。 +* Constructor 中是唯一一个你能直接赋值 [`this.state`](#state) 的地方。在其余所有方法中,你需要使用 [`this.setState()`](#setstate) 来代替。不要在 constructor 中使用 `setState`。 -* 当你使用 [服务端渲染](/reference/react-dom/server) 时,constructor 也将在服务端运行,紧接着运行 [`render`](#render) 方法。然而,像 `componentDidMount` 或者 `componentWillUnmount` 这样的生命周期方法将不会在服务端运行。 +* 当你使用 [服务端渲染](/reference/react-dom/server) 时,constructor 也将在服务端运行,然后紧接着会运行 [`render`](#render) 方法。然而,像 `componentDidMount` 或者 `componentWillUnmount` 这样的生命周期方法将不会在服务端运行。 -* 当 [严格模式](/reference/react/StrictMode) 打开时,React 将会在开发过程中调用两次 `constructor` 然后丢弃其中的一个实例。这有助于你注意到需要从 `constructor` 中移出的意外副作用。 +* 当 [严格模式](/reference/react/StrictMode) 打开时,React 将会在开发过程中调用两次 `constructor` 然后丢弃其中的一个实例。这有助于你注意到需要从 `constructor` 中移出的意外的副作用。 -在函数式组件中没有与 `constructor` 作用完全相同的函数。要在函数式组件中声明 state 请调用 [`useState`](/reference/react/useState) 来避免重新计算初始的 state。[传递一个函数给 `useState`](/reference/react/useState#avoiding-recreating-the-initial-state)。 +在函数式组件中没有与 `constructor` 作用完全相同的函数。要在函数式组件中声明 state 请调用 [`useState`](/reference/react/useState) 来避免重新计算初始的 state,[传递一个函数给 `useState`](/reference/react/useState#avoiding-recreating-the-initial-state)。 @@ -216,7 +216,7 @@ constructor 不应该包含任何副作用或者监听相关的代码。 ### `componentDidCatch(error, info)` {/*componentdidcatch*/} -如果你定义了 `componentDidCatch`,那么当某些子组件(包括后代组件)在渲染过程中抛出错误时 React 将调用它。这使得你可以在生产中将该错误记录到错误报告服务中。 +如果你定义了 `componentDidCatch`,那么 React 将在某些子组件(包括后代组件)在渲染过程中抛出错误时调用它。这使得你可以在生产中将该错误记录到错误报告服务中。 一般来说,它与 [`static getDerivedStateFromError`](#static-getderivedstatefromerror) 一起使用,这样做允许你更新 state 来响应错误并向用户显示错误消息。具有这些方法的组件称为 **错误边界**。 @@ -224,9 +224,9 @@ constructor 不应该包含任何副作用或者监听相关的代码。 #### 参数 {/*componentdidcatch-parameters*/} -* `error`:被抛出的错误。实际上,它通常会是一个 [`Error`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,不过这并不能保证,因为 JavaScript 允许 [`抛出`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/throw) 所有类型的值,包括字符串甚至是 `null`。 +* `error`:被抛出的错误。实际上,它通常会是一个 [`Error`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Error) 的实例,但是这并不能保证,因为 JavaScript 允许 [`抛出`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/throw) 所有值,包括字符串甚至是 `null`。 -* `info`:一个包含有关错误的附加信息的对象。它的 `componentStack` 字段包含一个堆栈跟踪,其中包含抛出的组件,以及其所有父组件的名称和源位置。在生产中,组件名称将被简化。如果你设置了生产错误报告服务,则可以使用源映射来解码组件堆栈,就像处理常规 JavaScript 错误堆栈一样。 +* `info`:一个包含有关错误的附加信息的对象。它的 `componentStack` 字段包含一个关于有关组件的堆栈跟踪,以及其所有父组件的名称和源位置。在生产中,组件名称将被简化。如果你设置了生产错误报告服务,则可以使用源映射来解码组件堆栈,就像处理常规 JavaScript 错误堆栈一样。 #### 返回值 {/*componentdidcatch-returns*/} @@ -234,9 +234,9 @@ constructor 不应该包含任何副作用或者监听相关的代码。 #### 注意 {/*componentdidcatch-caveats*/} -* 在以前经常会在 `componentDidCatch` 中使用 `setState` 来更新UI以及显示回退错误消息。这现在已被废弃,我们更赞同定义 [`static getDerivedStateFromError`](#static-getderivedstatefromerror)。 +* 在以前经常会在 `componentDidCatch` 中使用 `setState` 来更新 UI 以及显示回退错误消息。我们反对这种方法,更赞同定义 [`static getDerivedStateFromError`](#static-getderivedstatefromerror)。 -* `componentDidCatch` 在 React 生产环境和开发环境中处理错误的方式有所不同,在开发环境下,错误将冒泡至 `window`,这意味着任何 `window.onerror` 或者 `window.addEventListener('error', callback)` 都中断被 `componentDidCatch` 所捕获到的错误。而在生产环境下则相反,错误并不会冒泡,这意味着任何父级的错误处理器都只会接收到被 `componentDidCatch` 捕获的非显式错误。 +* `componentDidCatch` 在 React 生产环境和开发环境中处理错误的方式有所不同,在开发环境下,错误将冒泡至 `window`,这意味着任何 `window.onerror` 或者 `window.addEventListener('error', callback)` 事件都将中断被 `componentDidCatch` 所捕获到的错误。而在生产环境下则相反,错误并不会冒泡,这意味着任何父级的错误处理器都只会接收到被 `componentDidCatch` 捕获的非显式错误。 @@ -248,7 +248,7 @@ constructor 不应该包含任何副作用或者监听相关的代码。 ### `componentDidMount()` {/*componentdidmount*/} -如果你定义了 `componentDidMount` 方法,React 将会在组件被添加到屏幕上 **(挂载)** 后调用它。这里是设置数据获取、订阅监听事件或操作DOM节点的常见位置。 +如果你定义了 `componentDidMount` 方法,React 将会在组件被添加到屏幕上 **(挂载)** 后调用它。这里是设置数据获取、订阅监听事件或操作 DOM 节点的常见位置。 如果你要实现 `componentDidMount`,你通常需要设置一些其他的生命周期函数来避免出错。例如,如果 `componentDidMount` 读取一些 state 或者 props,你还必须要设置 [`componentDidUpdate`](#componentdidupdate) 来处理它们的更新,以及设置 [`componentWillUnmount`](#componentwillunmount) 来清理 `componentDidMount` 的效果。 @@ -294,7 +294,7 @@ class ChatRoom extends Component { - 当 [严格模式](/reference/react/StrictMode) 开启时,在开发环境中 React 会调用 `componentDidMount`,然后会立刻调用 [`componentWillUnmount`](#componentwillunmount),接着再次调用 `componentDidMount`。这将帮助你注意到你是否忘记设置 `componentWillUnmount` 或者它的逻辑是否完全对应到 `componentDidMount` 的效果。 -- 虽然你可以在 `componentDidMount` 中立即调用 [`setState`](#setstate),不过最好避免这样做。因为这将触发一次额外的渲染,但是这是在浏览器更新屏幕之前发生的。在这种情况下即使 [`render`](#render) 被调用了两次,用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下,你应该能在 [`constructor`](#constructor) 中设置初始的 state。但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 +- 虽然你可以在 `componentDidMount` 中立即调用 [`setState`](#setstate),不过最好避免这样做。因为这将触发一次浏览器更新屏幕之前发生的额外的渲染。在这种情况下即使 [`render`](#render) 被调用了两次,用户也无法看到中间的状态。请谨慎使用这种模式因为它可能会造成性能问题。在大多数情况下,你应该能在 [`constructor`](#constructor) 中设置初始的 state。但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 @@ -310,7 +310,7 @@ class ChatRoom extends Component { 如果你定义了 `componentDidUpdate` 方法,那么 React 会在你的组件更新了 props 或 state 重新渲染后立即调用它。这个方法不会在首次渲染时调用。 -你可以在一次更新后使用它来操作 DOM。处理网络请求时也可能会使用这个方法,将当前的 props 与以前的 props 进行比较(例如,如果 props 没有更改,则可能不需要网络请求)。一般来说,这个方法与 [`componentDidMount`](#componentdidmount) 以及 [`componentWillUnmount`](#componentwillunmount) 一起使用: +你可以在一次更新后使用它来操作 DOM。处理网络请求时也可能会使用这个方法,只要你将当前的 props 与以前的 props 进行比较(因为,如果 props 没有更改,则可能不需要网络请求)。这个方法一般会和 [`componentDidMount`](#componentdidmount) 以及 [`componentWillUnmount`](#componentwillunmount) 一起使用: ```js {10-18} class ChatRoom extends Component { @@ -359,9 +359,9 @@ class ChatRoom extends Component { - 如果你定义了 [`shouldComponentUpdate`](#shouldcomponentupdate) 并且返回值是 `false` 的话,那么 `componentDidUpdate` 将不会被调用。 -- `componentDidUpdate` 内部的逻辑通常应该包含在比较 `this.props` 与 `prevProps` 以及 `this.state` 与 `prevState` 之中。否则就会存在创建无限循环的风险。 +- `componentDidUpdate` 内部的逻辑通常应该包含在比较 `this.props` 与 `prevProps` 以及 `this.state` 与 `prevState` 的条件之中。否则就会存在创建无限循环的风险。 -- 虽然可以在 `componentDidUpdate` 中直接调用 [`setState`](#setstate),但最好尽可能避免这样做。因为它将触发一次额外的渲染,而且是在浏览器更新屏幕内容之前发生的。在这种情况下,即使 [`render`](#render) 会被调用两次,用户也看不到中间状态。这种模式通常会导致性能问题,但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 +- 虽然你可以在 `componentDidUpdate` 中直接调用 [`setState`](#setstate),但最好尽可能避免这样做。因为它将触发一次发生在浏览器更新屏幕内容之前的额外渲染,在这种情况下,即使 [`render`](#render) 会被调用两次,用户也看不到中间状态。这种模式通常会导致性能问题,但是对于 modal 和 tooltip 等当你的渲染依赖于 DOM 节点的大小或位置情况下,这种方法可能是必要的。 @@ -470,7 +470,7 @@ class ChatRoom extends Component { 强制组件重新渲染。 -通常来说,这是没必要的。如果组件的 [`render`](#render) 方法仅读取了 [`this.props`](#props)、[`this.state`](#state) 或 [`this.context`]( #context) 时,当你在组件或其任一父组件内调用 [`setState`](#setstate) 时,它就将自动重新渲染。但是,如果组件的 `render` 方法是直接读取外部数据源时,则必须告诉 React 在该数据源更改时更新用户界面。这就是 `forceUpdate` 的作用。 +通常来说,这是没必要的。如果组件的 [`render`](#render) 方法仅读取了 [`this.props`](#props)、[`this.state`](#state) 或 [`this.context`]( #context) 时,当你在组件或其任一父组件内调用 [`setState`](#setstate) 时,它就将自动重新渲染。但是如果组件的 `render` 方法是直接读取外部数据源时,则必须告诉 React 在该数据源更改时更新用户界面。这就是 `forceUpdate` 的作用。 尽量避免使用 `forceUpdate` 并且在 `render` 中尽量只读取 `this.props` 和 `this.state`。 @@ -502,7 +502,7 @@ class ChatRoom extends Component { -允许你指定由该组件提供的 [非法的 context](https://reactjs.org/docs/legacy-context.html) 的值。 +允许你指定由该组件提供的 [历史用法的 context](https://reactjs.org/docs/legacy-context.html) 的值。 --- @@ -532,7 +532,7 @@ class ScrollingList extends React.Component { componentDidUpdate(prevProps, prevState, snapshot) { // 如果我们有快照值,那么说明我们刚刚添加了新内容。 // 调整滚动,使得这些新内容不会将旧内容推出视野。 - // (这里的 snapshot 是 getSnapshotBeforeUpdate 返回的值) + //(这里的 snapshot 是 getSnapshotBeforeUpdate 返回的值) if (snapshot !== null) { const list = this.listRef.current; list.scrollTop = list.scrollHeight - snapshot; @@ -547,7 +547,7 @@ class ScrollingList extends React.Component { } ``` -在上面的示例中,能直接在 `getSnapshotBeforeUpdate` 中读取到 `scrollHeight` 属性非常重要。在 [`render`](#render)、[`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops) 或 [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate) 中读取它是不安全的,因为这些方法被调用与 React 更新 DOM 之间存在潜在的时间间隔。 +在上面的示例中,能直接在 `getSnapshotBeforeUpdate` 中读取到 `scrollHeight` 属性非常重要。在 [`render`](#render)、[`UNSAFE_componentWillReceiveProps`](#unsafe_componentwillreceiveprops) 或 [`UNSAFE_componentWillUpdate`](#unsafe_componentwillupdate) 中读取它是不安全的,因为这些方法的调用与 React 更新 DOM 之间存在潜在的时间间隔。 #### 参数 {/*getsnapshotbeforeupdate-parameters*/} @@ -795,7 +795,7 @@ class Rectangle extends Component { -在类式组件中的 `UNSAFE_componentWillMount` 内部调用 [`setState`](#setstate) 来初始化状态等同于函数式组件中用该 state 作为初始 state 传递给 [`useState`]。 +在类式组件中的 `UNSAFE_componentWillMount` 内部调用 [`setState`](#setstate) 来初始化状态等同于函数式组件中用该 state 作为初始 state 传递给 [`useState`](/reference/react/useState)。 @@ -833,7 +833,7 @@ class Rectangle extends Component { -在类式组件中的 `UNSAFE_componentWillReceiveProps` 里调用 [`setState`](#setstate) 来“调整”state 等同于在函数式组件在 [渲染期间从 `useState` 调用 `set` 函数](/reference/react/useState#storing-information-from-previous-renders)。 +在类式组件中的 `UNSAFE_componentWillReceiveProps` 里调用 [`setState`](#setstate) 来“调整”state 等同于在函数式组件在 [渲染期间调用来自 `useState` 的 `set` 函数](/reference/react/useState#storing-information-from-previous-renders)。 @@ -888,7 +888,7 @@ class Rectangle extends Component { -允许你指定此组件提供哪个 [过时的 context](https://reactjs.org/docs/legacy-context.html)。 +允许你指定此组件提供哪个 [历史用法的 context](https://reactjs.org/docs/legacy-context.html)。 --- @@ -900,7 +900,7 @@ class Rectangle extends Component { -允许你指定此组件使用哪个 [过时的 context](https://reactjs.org/docs/legacy-context.html)。 +允许你指定此组件使用哪个 [历史用法的 context](https://reactjs.org/docs/legacy-context.html)。 --- @@ -926,7 +926,7 @@ class Button extends Component { -在类式组件中读取 `this.context` 等同于在函数式组件中读取 [`useContext`](/reference/react/useContext)。 +在类式组件中读取 `this.context` 等同于在函数式组件中使用 [`useContext`](/reference/react/useContext)。 [了解如何迁移](#migrating-a-component-with-context-from-a-class-to-a-function)。 @@ -1036,7 +1036,7 @@ class Greeting extends React.Component { ### `static getDerivedStateFromProps(props, state)` {/*static-getderivedstatefromprops*/} -如果你定义了 `static getDerivedStateFromProps`,React 会在初始挂载和后续更新调用 [`render`](#render) 的之前调用它。它应该返回一个对象来更新 state,或者返回 `null` 就不更新任何内容。 +如果你定义了 `static getDerivedStateFromProps`,React 会在初始挂载和后续更新时调用 [`render`](#render) 之前调用它。它应该返回一个对象来更新 state,或者返回 `null` 就不更新任何内容。 此方法适用于 [少数罕见用例](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state),其中 state 取决于 props 随着时间的推移的变化。例如,当 `userID` 属性更改时,此 `Form` 组件会重置 `email` 状态: @@ -1064,15 +1064,15 @@ class Form extends Component { } ``` -请注意,此模式要求你将 prop 的先前值(如 `userID` )保留在 state(如 `prevUserID` )中。 +请注意,此模式要求你将 prop 的先前值(如 `userID`)保留在 state(如 `prevUserID`)中。 派生 state 会导致代码冗长,并使你的组件难以理解。[确保你熟悉这些更简单的替代方案](https://legacy.reactjs.org/blog/2018/06/07/you-probously-dont-need-driven-state.html): - 如果你需要 **执行副作用**(例如,数据获取或动画)以响应 props 的更改,请改用 [`componentDidUpdate`](#componentdidupdate) 方法。 -- 如果你想 **仅在 prop 更改时重新计算一些数据**,[使用记忆助手代替](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization)。 --如果你想要 **当 prop 改变时“重置”一些 state**,请考虑使组件 [完全控制](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) 或者 [使用 key 使组件完全不受控](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key)。 +- 如果你想 **仅在 prop 更改时重新计算一些数据**,[使用 memoization helper 代替](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization)。 +- 如果你想要 **当 prop 改变时“重置”一些 state**,请考虑使组件 [完全控制](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component) 或者 [使用 key 使组件完全不受控](https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key)。 @@ -1089,7 +1089,7 @@ class Form extends Component { - 无论什么原因,此方法都会在 **每次** 渲染时触发。这与 [`UNSAFE_componentWillReceiveProps`](#unsafe_cmoponentwillreceiveprops) 不同,后者仅在父组件不是因为调用了本地的 `setState` 而重新渲染时触发。 -- 此方法无权访问组件实例。如果你愿意,您可以在 `static getDerivedStateFromProps` 和其他类方法之间重用一些代码,也就是提取类定义之外的组件 props 和 state 的纯函数。 +- 此方法无权访问组件实例。如果你愿意,你可以在 `static getDerivedStateFromProps` 和其他类方法之间重用一些代码,也就是提取类定义之外的组件 props 和 state 的纯函数。 @@ -1103,7 +1103,7 @@ class Form extends Component { ### 定义类式组件 {/*defining-a-class-component*/} -要将 React 组件定义为类,请扩展内置的 `Component` 类并定义 [`render` 方法](#render): +要将 React 组件定义为类,请继承内置的 `Component` 类并定义 [`render` 方法](#render): ```js import { Component } from 'react'; @@ -1215,9 +1215,9 @@ button { display: block; margin-top: 10px; } 你可以在类中定义一些特殊方法。 -如果你定义了 [`componentDidMount`](#componentdidmount) 方法,当你的组件被添加到屏幕上(**挂载**)时,React 将会调用它。当你的组件由于 props 或 state 改变而重新渲染后,React 将调用 [`componentDidUpdate`](#componentdidupdate)。当你的组件从屏幕上被移除(**卸载**)后,React 将调用 [`componentWillUnmount`](#componentwillunmount)。 +如果你定义了 [`componentDidMount`](#componentdidmount) 方法,当你的组件被添加到屏幕上(**挂载**)时,React 将会调用它。当你的组件由于 props 或 state 改变而重新渲染后,React 将调用 [`componentDidUpdate`](#componentdidupdate)。当你的组件从屏幕上被移除(**卸载**)后,React 将调用 [`componentWillUnmount`](#componentwillunmount) 方法。 -如果你实现了 `componentDidMount`,通常需要实现所有三个生命周期以避免错误。例如,如果 `componentDidMount` 读取某些 state 或属性,你还必须实现 `componentDidUpdate` 来处理它们的更改,并实现 `componentWillUnmount` 来清理 `componentDidMount` 所执行的所有操作。 +如果你实现了 `componentDidMount` 方法,那么通常还需要实现所有三个生命周期以避免错误。例如,如果 `componentDidMount` 读取了某些 state 或属性,你就还必须实现 `componentDidUpdate` 来处理它们的更改,并且实现 `componentWillUnmount` 来清理 `componentDidMount` 所执行的所有操作。 例如,这个 `ChatRoom` 组件使聊天连接与 props 和 state 保持同步: @@ -1374,7 +1374,7 @@ class ErrorBoundary extends React.Component { render() { if (this.state.hasError) { - // 您可以渲染任何自定义后备 UI + // 你可以渲染任何自定义后备 UI return this.props.fallback; } From cbe2d4e30371fa76ecafd678e25c5c8ff5bf591e Mon Sep 17 00:00:00 2001 From: Tosuke <1848228664@qq.com> Date: Wed, 26 Jul 2023 15:09:37 +0800 Subject: [PATCH 11/13] fix: fix error --- src/content/reference/react/Component.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index 651daa8810..c9c3eee449 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -50,7 +50,7 @@ class Greeting extends Component { ### `context` {/*context*/} -可以通过使用 `this.context` 来访问一个类式组件的 [context](/learn/passing-data-deeply-with-context)。只有当你使用 [`static contextType`](#static-contexttype)(最新的)或者 [`static contextTypes`](#static-contexttypes)(已被废弃的)来特别指定你想要接受 **哪一个** context 时它才会有效。 +类式组件可以通过使用 `this.context` 访问 [context](/learn/passing-data-deeply-with-context)。只有使用 [`static contextType`](#static-contexttype)(最新的)或者 [`static contextTypes`](#static-contexttypes)(已废弃)特别指定想要接受 **哪一个** context 时才会有效。 类式组件一次只能读取一个 context。 From dad350d9e7118c3ca23ffb9fee86d4ef41d75745 Mon Sep 17 00:00:00 2001 From: Xavi Lee Date: Fri, 28 Jul 2023 19:54:16 +0800 Subject: [PATCH 12/13] Apply suggestions from code review --- src/content/reference/react/Component.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index c9c3eee449..c533c2e2be 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -345,9 +345,9 @@ class ChatRoom extends Component { #### 参数 {/*componentdidupdate-parameters*/} -* `prevProps`:更新之前的 Props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定发生了什么改变。 +* `prevProps`:更新之前的 props。`prevProps` 将会与 [`this.props`](#props) 进行比较来确定发生了什么改变。 -* `prevState`:更新之前的 State。`prevState` 将会与 [`this.state`](#state) 进行比较来确定发生了什么改变。 +* `prevState`:更新之前的 state。`prevState` 将会与 [`this.state`](#state) 进行比较来确定发生了什么改变。 * `snapshot`:如果你实现了 [`getSnapshotBeforeUpdate`](#getsnapshotbeforeupdate) 方法,那么 `snapshot` 将包含从该方法返回的值。否则它将是 `undefined`。 From 8a24963a7399068768f1d23e9873182f8ef89dc3 Mon Sep 17 00:00:00 2001 From: Xavi Lee Date: Fri, 28 Jul 2023 19:58:21 +0800 Subject: [PATCH 13/13] Update src/content/reference/react/Component.md --- src/content/reference/react/Component.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index c533c2e2be..3ef7d22d6f 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -113,7 +113,7 @@ class Greeting extends Component { -允许你获取此组件的 [历史用法的字符串 ref](https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs)。 +允许你获取此组件 [过时的字符串 ref](https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs)。 ---