From c271380b52b1cf4bba3ace9d692b8363223b5440 Mon Sep 17 00:00:00 2001 From: newvo1d Date: Tue, 30 May 2023 10:56:21 +0800 Subject: [PATCH 1/7] docs(cn): translate /reference/react/StrictMode into Chinese --- src/content/reference/react/StrictMode.md | 243 +++++++++++----------- 1 file changed, 121 insertions(+), 122 deletions(-) diff --git a/src/content/reference/react/StrictMode.md b/src/content/reference/react/StrictMode.md index b7ca2227c5..88e619d4b2 100644 --- a/src/content/reference/react/StrictMode.md +++ b/src/content/reference/react/StrictMode.md @@ -5,7 +5,7 @@ title: -`` lets you find common bugs in your components early during development. +`` 帮助你在开发过程中尽早地发现组件中的常见错误。 ```js @@ -20,11 +20,11 @@ title: --- -## Reference {/*reference*/} +## 参考 {/*reference*/} ### `` {/*strictmode*/} -Use `StrictMode` to enable additional development behaviors and warnings for the component tree inside: +使用 `StrictMode` 来启用组件树内部的额外开发行为和警告: ```js import { StrictMode } from 'react'; @@ -38,32 +38,31 @@ root.render( ); ``` -[See more examples below.](#usage) +[以下是更多的示例](#usage)。 -Strict Mode enables the following development-only behaviors: +严格模式启用了以下仅在开发环境下有效的行为: -- Your components will [re-render an extra time](#fixing-bugs-found-by-double-rendering-in-development) to find bugs caused by impure rendering. -- Your components will [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) to find bugs caused by missing Effect cleanup. -- Your components will [be checked for usage of deprecated APIs.](#fixing-deprecation-warnings-enabled-by-strict-mode) +- 组件将 [重新渲染一次](#fixing-bugs-found-by-double-rendering-in-development),以查找由于非纯渲染而引起的错误。 +- 组件将 [重新运行 Effects 一次](#fixing-bugs-found-by-re-running-effects-in-development),以查找由于缺少 Effect 清理而引起的错误。 +- 组件将被[检查是否使用了已弃用的 API](#fixing-deprecation-warnings-enabled-by-strict-mode)。 -#### Props {/*props*/} +#### 参数 {/*props*/} -`StrictMode` accepts no props. +`StrictMode` 不接受任何参数。 -#### Caveats {/*caveats*/} +#### 注意事项 {/*caveats*/} -* There is no way to opt out of Strict Mode inside a tree wrapped in ``. This gives you confidence that all components inside `` are checked. If two teams working on a product disagree whether they find the checks valuable, they need to either reach consensus or move `` down in the tree. +* 在由 `` 包裹的树中,无法选择退出严格模式。这可以确保在 `` 内的所有组件都经过检查。如果两个团队在一个产品上工作,对于是否认为这些检查有价值存在分歧,他们需要达成共识或将 `` 下移到树的较低层级。 --- -## Usage {/*usage*/} +## 用法 {/*usage*/} -### Enabling Strict Mode for entire app {/*enabling-strict-mode-for-entire-app*/} +### 为整个应用启用严格模式 {/*enabling-strict-mode-for-entire-app*/} -Strict Mode enables extra development-only checks for the entire component tree inside the `` component. These checks help you find common bugs in your components early in the development process. +严格模式为 `` 组件内的整个组件树启用额外的开发环境检查,这些检查有助于在开发过程中尽早地发现组件中的常见错误。 - -To enable Strict Mode for your entire app, wrap your root component with `` when you render it: +如果要为整个应用启用严格模式,请在渲染根组件时使用 `` 包裹它: ```js {6,8} import { StrictMode } from 'react'; @@ -77,27 +76,27 @@ root.render( ); ``` -We recommend wrapping your entire app in Strict Mode, especially for newly created apps. If you use a framework that calls [`createRoot`](/reference/react-dom/client/createRoot) for you, check its documentation for how to enable Strict Mode. +我们建议将整个应用程序包裹在严格模式中,特别是对于新创建的应用程序。如果你使用的是一个调用 [`createRoot`](/reference/react-dom/client/createRoot) 的框架,请查阅其文档以了解如何启用严格模式。 -Although the Strict Mode checks **only run in development,** they help you find bugs that already exist in your code but can be tricky to reliably reproduce in production. Strict Mode lets you fix bugs before your users report them. +尽管严格模式的检查**仅在开发环境**下运行,但它们有助于找出已经存在于代码中但在生产环境中可能难以复现的错误。严格模式让你在用户反馈之前就可以修复这些错误。 -Strict Mode enables the following checks in development: +严格模式启用了以下仅在开发环境下有效的行为: -- Your components will [re-render an extra time](#fixing-bugs-found-by-double-rendering-in-development) to find bugs caused by impure rendering. -- Your components will [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) to find bugs caused by missing Effect cleanup. -- Your components will [be checked for usage of deprecated APIs.](#fixing-deprecation-warnings-enabled-by-strict-mode) +- 组件将 [重新渲染一次](#fixing-bugs-found-by-double-rendering-in-development),以查找由于非纯渲染而引起的错误。 +- 组件将 [重新运行 Effects 一次](#fixing-bugs-found-by-re-running-effects-in-development),以查找由于缺少 Effect 清理而引起的错误。 +- 组件将被[检查是否使用了已弃用的 API](#fixing-deprecation-warnings-enabled-by-strict-mode)。 -**All of these checks are development-only and do not impact the production build.** +**所有这些检查仅在开发环境中进行,不会影响生产构建。** --- -### Enabling strict mode for a part of the app {/*enabling-strict-mode-for-a-part-of-the-app*/} +### 为应用的一部分启用严格模式 {/*enabling-strict-mode-for-a-part-of-the-app*/} -You can also enable Strict Mode for any part of your application: +你也可以为应用程序的任意一部分启用严格模式: ```js {7,12} import { StrictMode } from 'react'; @@ -118,25 +117,25 @@ function App() { } ``` -In this example, Strict Mode checks will not run against the `Header` and `Footer` components. However, they will run on `Sidebar` and `Content`, as well as all of the components inside them, no matter how deep. +在这个例子中,严格模式的检查不会对 `Header` 和 `Footer` 组件运行。然而,它们会在 `Sidebar` 和 `Content` 以及它们内部的所有组件上运行,无论多深。 --- -### Fixing bugs found by double rendering in development {/*fixing-bugs-found-by-double-rendering-in-development*/} +### 修复在开发过程中通过双重渲染发现的错误 {/*fixing-bugs-found-by-double-rendering-in-development*/} -[React assumes that every component you write is a pure function.](/learn/keeping-components-pure) This means that React components you write must always return the same JSX given the same inputs (props, state, and context). +[React假设您编写的每个组件都是纯函数](/learn/keeping-components-pure)。这意味着您编写的 React 组件在给定相同的输入(props、state 和 context)时必须始终返回相同的 JSX。 -Components breaking this rule behave unpredictably and cause bugs. To help you find accidentally impure code, Strict Mode calls some of your functions (only the ones that should be pure) **twice in development.** This includes: +违反此规则的组件会表现得不可预测,并引发错误。为了帮助你找到意外的非纯代码,严格模式**在开发环境中会调用一些函数两次**(仅限应为纯函数的函数)。这些函数包括: -- Your component function body (only top-level logic, so this doesn't include code inside event handlers) -- Functions that you pass to [`useState`](/reference/react/useState), [`set` functions](/reference/react/useState#setstate), [`useMemo`](/reference/react/useMemo), or [`useReducer`](/reference/react/useReducer) -- Some class component methods like [`constructor`](/reference/react/Component#constructor), [`render`](/reference/react/Component#render), [`shouldComponentUpdate`](/reference/react/Component#shouldcomponentupdate) ([see the whole list](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects)) +- 组件函数体(仅限顶层逻辑,不包括事件处理程序内的代码) +- 传递给 [`useState`](/reference/react/useState)、[`set 函数`](/reference/react/useState#setstate)、[`useMemo`](/reference/react/useMemo) 或 [`useReducer`](/reference/react/useReducer) 的函数。 +- 部分类组件的方法,例如 [`constructor`](/reference/react/Component#constructor)、[`render`](/reference/react/Component#render)、[`shouldComponentUpdate`](/reference/react/Component#shouldcomponentupdate) 等([请参阅完整列表](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects))。 -If a function is pure, running it twice does not change its behavior because a pure function produces the same result every time. However, if a function is impure (for example, it mutates the data it receives), running it twice tends to be noticeable (that's what makes it impure!) This helps you spot and fix the bug early. +如果一个函数是纯函数,运行两次不会改变其行为,因为纯函数每次都会产生相同的结果。然而,如果一个函数是非纯函数(例如,它会修改接收到的数据),运行两次通常会产生明显的差异(这就是它是非纯函数的原因!)。这有助于您及早发现并修复错误。 -**Here is an example to illustrate how double rendering in Strict Mode helps you find bugs early.** +**下面是一个示例,用来说明严格模式中的双重渲染如何帮助你早期发现错误**。 -This `StoryTray` component takes an array of `stories` and adds one last "Create Story" item at the end: +这个 `StoryTray` 组件接收一个 `stories` 数组,并在末尾添加一个额外的“创建故事”节点: @@ -155,8 +154,8 @@ import { useState } from 'react'; import StoryTray from './StoryTray.js'; let initialStories = [ - {id: 0, label: "Ankit's Story" }, - {id: 1, label: "Taylor's Story" }, + {id: 0, label: "安琪的故事" }, + {id: 1, label: "泰勒的故事" }, ]; export default function App() { @@ -178,7 +177,7 @@ export default function App() { ```js StoryTray.js active export default function StoryTray({ stories }) { const items = stories; - items.push({ id: 'create', label: 'Create Story' }); + items.push({ id: 'create', label: '创建故事' }); return (
    {items.map(story => ( @@ -212,9 +211,9 @@ li { -There is a mistake in the code above. However, it is easy to miss because the initial output appears correct. +上面的代码中有一个错误,但很容易忽视,因为初始输出看起来是正确的。 -This mistake will become more noticeable if the `StoryTray` component re-renders multiple times. For example, let's make the `StoryTray` re-render with a different background color whenever you hover over it: +如果 `StoryTray` 组件重新渲染多次,这个错误将变得更加明显。例如,让我们在鼠标悬停在 `StoryTray` 组件上时,以不同的背景颜色重新渲染它: @@ -233,8 +232,8 @@ import { useState } from 'react'; import StoryTray from './StoryTray.js'; let initialStories = [ - {id: 0, label: "Ankit's Story" }, - {id: 1, label: "Taylor's Story" }, + {id: 0, label: "安琪的故事" }, + {id: 1, label: "泰勒的故事" }, ]; export default function App() { @@ -259,7 +258,7 @@ import { useState } from 'react'; export default function StoryTray({ stories }) { const [isHover, setIsHover] = useState(false); const items = stories; - items.push({ id: 'create', label: 'Create Story' }); + items.push({ id: 'create', label: '创建故事' }); return (
      setIsHover(true)} @@ -299,20 +298,20 @@ li { -Notice how every time you hover over the `StoryTray` component, "Create Story" gets added to the list again. The intention of the code was to add it once at the end. But `StoryTray` directly modifies the `stories` array from the props. Every time `StoryTray` renders, it adds "Create Story" again at the end of the same array. In other words, `StoryTray` is not a pure function--running it multiple times produces different results. +注意,每次在 `StoryTray` 组件上悬停时,“创建故事”都会再次添加到列表中。代码的本意是将它添加到列表的末尾一次。但是,`StoryTray` 直接修改了传入的 `stories` 数组。每次 `StoryTray` 重新渲染时,它会再次将“创建故事”添加到相同的数组末尾。换句话说,`StoryTray` 不是一个纯函数——多次运行它会产生不同的结果。 -To fix this problem, you can make a copy of the array, and modify that copy instead of the original one: +为了解决这个问题,你可以创建数组的副本并修改该副本,而不是修改原始数组: ```js {2} export default function StoryTray({ stories }) { - const items = stories.slice(); // Clone the array - // ✅ Good: Pushing into a new array + const items = stories.slice(); // 复制数组 + // ✅ 正确的:在新数组上进行修改 items.push({ id: 'create', label: 'Create Story' }); ``` -This would [make the `StoryTray` function pure.](/learn/keeping-components-pure) Each time it is called, it would only modify a new copy of the array, and would not affect any external objects or variables. This solves the bug, but you had to make the component re-render more often before it became obvious that something is wrong with its behavior. +这样做会[使 `StoryTray` 函数成为纯函数](/learn/keeping-components-pure)。每次调用函数时,它只会修改一个新的数组副本,不会影响任何外部对象或变量。这解决了错误,但在发现其行为有问题之前,你可能需要更频繁地使组件重新渲染。 -**In the original example, the bug wasn't obvious. Now let's wrap the original (buggy) code in ``:** +**在原始的例子中,这个错误并不明显。现在让我们将原始有错误的代码包裹在 `` 中:** @@ -336,8 +335,8 @@ import { useState } from 'react'; import StoryTray from './StoryTray.js'; let initialStories = [ - {id: 0, label: "Ankit's Story" }, - {id: 1, label: "Taylor's Story" }, + {id: 0, label: "安琪的故事" }, + {id: 1, label: "泰勒的故事" }, ]; export default function App() { @@ -359,7 +358,7 @@ export default function App() { ```js StoryTray.js active export default function StoryTray({ stories }) { const items = stories; - items.push({ id: 'create', label: 'Create Story' }); + items.push({ id: 'create', label: '创建故事' }); return (
        {items.map(story => ( @@ -393,7 +392,7 @@ li { -**Strict Mode *always* calls your rendering function twice, so you can see the mistake right away** ("Create Story" appears twice). This lets you notice such mistakes early in the process. When you fix your component to render in Strict Mode, you *also* fix many possible future production bugs like the hover functionality from before: +**严格模式*始终*会调用您的渲染函数两次**,这样您就可以立即发现错误(“创建故事”出现两次)。这让您能够在早期阶段注意到此类错误。当您修复组件以在严格模式下进行渲染时,您也会修复许多可能的未来生产错误,例如之前的悬停功能: @@ -417,8 +416,8 @@ import { useState } from 'react'; import StoryTray from './StoryTray.js'; let initialStories = [ - {id: 0, label: "Ankit's Story" }, - {id: 1, label: "Taylor's Story" }, + {id: 0, label: "安琪的故事" }, + {id: 1, label: "泰勒的故事" }, ]; export default function App() { @@ -442,8 +441,8 @@ import { useState } from 'react'; export default function StoryTray({ stories }) { const [isHover, setIsHover] = useState(false); - const items = stories.slice(); // Clone the array - items.push({ id: 'create', label: 'Create Story' }); + const items = stories.slice(); // 复制数组 + items.push({ id: 'create', label: '创建故事' }); return (
          setIsHover(true)} @@ -483,29 +482,29 @@ li { -Without Strict Mode, it was easy to miss the bug until you added more re-renders. Strict Mode made the same bug appear right away. Strict Mode helps you find bugs before you push them to your team and to your users. +在没有严格模式的情况下,在你添加了更多的重新渲染前很容易忽视这个错误。而严格模式立即显示了相同的错误。严格模式可以帮助你在将错误推送给团队和用户之前发现它们。 -[Read more about keeping components pure.](/learn/keeping-components-pure) +[更多请阅读保持组件纯粹](/learn/keeping-components-pure)。 -If you have [React DevTools](/learn/react-developer-tools) installed, any `console.log` calls during the second render call will appear slightly dimmed. React DevTools also offers a setting (off by default) to suppress them completely. +如果您已经安装了 [React DevTools](/learn/react-developer-tools),在第二次渲染期间进行的任何 `console.log` 调用将会显示为稍微变暗的颜色。React DevTools 还提供了一个设置(默认情况下关闭),可以完全禁止显示这些日志。 --- -### Fixing bugs found by re-running Effects in development {/*fixing-bugs-found-by-re-running-effects-in-development*/} +### 修复在开发中通过重新运行 Effects 发现的错误 {/*fixing-bugs-found-by-re-running-effects-in-development*/} -Strict Mode can also help find bugs in [Effects.](/learn/synchronizing-with-effects) +严格模式也可以帮助发现 [Effects](/learn/synchronizing-with-effects) 中的错误。 -Every Effect has some setup code and may have some cleanup code. Normally, React calls setup when the component *mounts* (is added to the screen) and calls cleanup when the component *unmounts* (is removed from the screen). React then calls cleanup and setup again if its dependencies changed since the last render. +每个 Effect 都有一些 setup 和可能的 cleanup 。通常情况下,当组件*挂载*(添加到屏幕)时,React 会调用设置代码,当组件*卸载*(从屏幕移除)时,React 会调用清理代码。如果依赖关系在上一次渲染之后发生了变化,React 将再次调用清理代码和设置代码。 -When Strict Mode is on, React will also run **one extra setup+cleanup cycle in development for every Effect.** This may feel surprising, but it helps reveal subtle bugs that are hard to catch manually. +当开启严格模式时,React 还会在开发模式下为每个 Effect **额外运行一次setup 和 cleanup**。这可能会让人感到惊讶,但它有助于发现手动难以捕捉到的细微错误。 -**Here is an example to illustrate how re-running Effects in Strict Mode helps you find bugs early.** +**下面是一个例子,用来说明在严格模式下重新运行 Effects 如何帮助您早期发现错误。** -Consider this example that connects a component to a chat: +参考以下将组件连接到聊天功能的示例: @@ -524,14 +523,14 @@ import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; -const roomId = 'general'; +const roomId = '所有'; export default function ChatRoom() { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); }, []); - return

          Welcome to the {roomId} room!

          ; + return

          欢迎来到 {roomId} 聊天室!

          ; } ``` @@ -539,17 +538,17 @@ export default function ChatRoom() { let connections = 0; export function createConnection(serverUrl, roomId) { - // A real implementation would actually connect to the server + // 实际的实现将会连接到服务器 return { connect() { - console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); + console.log('✅ 连接到 "' + roomId + '" 聊天室,位于' + serverUrl + '...'); connections++; - console.log('Active connections: ' + connections); + console.log('活跃连接数: ' + connections); }, disconnect() { - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl); + console.log('❌ 断开 "' + roomId + '" 聊天室,位于' + serverUrl); connections--; - console.log('Active connections: ' + connections); + console.log('活跃连接数: ' + connections); } }; } @@ -562,9 +561,9 @@ button { margin-left: 10px; }
          -There is an issue with this code, but it might not be immediately clear. +这段代码存在一个问题,但可能并不明显。 -To make the issue more obvious, let's implement a feature. In the example below, `roomId` is not hardcoded. Instead, the user can select the `roomId` that they want to connect to from a dropdown. Click "Open chat" and then select different chat rooms one by one. Keep track of the number of active connections in the console: +为了更直观地展示这个问题,让我们实现一个功能。在下面的示例中,`roomId` 不是硬编码的,而是用户可以从下拉菜单中选择要连接的 `roomId`。点击“打开聊天”,然后依次选择不同的聊天室。在控制台中跟踪活跃连接的数量: @@ -590,27 +589,27 @@ function ChatRoom({ roomId }) { connection.connect(); }, [roomId]); - return

          Welcome to the {roomId} room!

          ; + return

          欢迎来到 {roomId} 聊天室!

          ; } export default function App() { - const [roomId, setRoomId] = useState('general'); + const [roomId, setRoomId] = useState('所有'); const [show, setShow] = useState(false); return ( <> {show &&
          } {show && } @@ -623,17 +622,17 @@ export default function App() { let connections = 0; export function createConnection(serverUrl, roomId) { - // A real implementation would actually connect to the server + // 实际的实现将会连接到服务器 return { connect() { - console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); + console.log('✅ 连接到 "' + roomId + '" 聊天室,位于' + serverUrl + '...'); connections++; - console.log('Active connections: ' + connections); + console.log('活跃连接数: ' + connections); }, disconnect() { - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl); + console.log('❌ 断开 "' + roomId + '" 聊天室,位于' + serverUrl); connections--; - console.log('Active connections: ' + connections); + console.log('活跃连接数: ' + connections); } }; } @@ -646,7 +645,7 @@ button { margin-left: 10px; }
          -You'll notice that the number of open connections always keeps growing. In a real app, this would cause performance and network problems. The issue is that [your Effect is missing a cleanup function:](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed) +你会注意到打开的连接数量一直在增加。在真实的应用程序中,这会导致性能和网络问题。问题出在[你的 Effect 缺少清理函数](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed): ```js {4} useEffect(() => { @@ -656,9 +655,9 @@ You'll notice that the number of open connections always keeps growing. In a rea }, [roomId]); ``` -Now that your Effect "cleans up" after itself and destroys the outdated connections, the leak is solved. However, notice that the problem did not become visible until you've added more features (the select box). +现在你的 Effect 在自身执行清理并销毁过时的连接后,问题被解决了。但是请注意,在添加了更多功能(下拉框)之前,这个问题很难被发现。 -**In the original example, the bug wasn't obvious. Now let's wrap the original (buggy) code in ``:** +**在原始的例子中,这个错误并不明显。现在让我们将原始有错误的代码包裹在 `` 中:** @@ -682,14 +681,14 @@ import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; -const roomId = 'general'; +const roomId = '所有'; export default function ChatRoom() { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); }, []); - return

          Welcome to the {roomId} room!

          ; + return

          欢迎来到 {roomId} 聊天室!

          ; } ``` @@ -697,17 +696,17 @@ export default function ChatRoom() { let connections = 0; export function createConnection(serverUrl, roomId) { - // A real implementation would actually connect to the server + // 实际的实现将会连接到服务器 return { connect() { - console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); + console.log('✅ 连接到 "' + roomId + '" 聊天室,位于' + serverUrl + '...'); connections++; - console.log('Active connections: ' + connections); + console.log('活跃连接数: ' + connections); }, disconnect() { - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl); + console.log('❌ 断开 "' + roomId + '" 聊天室,位于' + serverUrl); connections--; - console.log('Active connections: ' + connections); + console.log('活跃连接数: ' + connections); } }; } @@ -720,9 +719,9 @@ button { margin-left: 10px; }
          -**With Strict Mode, you immediately see that there is a problem** (the number of active connections jumps to 2). Strict Mode runs an extra setup+cleanup cycle for every Effect. This Effect has no cleanup logic, so it creates an extra connection but doesn't destroy it. This is a hint that you're missing a cleanup function. +**在严格模式下,你立即就能看到存在问题**(活跃连接的数量增加到了2个)。严格模式会为每个 Effect 运行额外一次 setup + cleanup。这个 Effect 没有 cleanup 逻辑,所以它创建了一个额外的连接但没有销毁它。这是一个提示,你可能忘记了添加清理函数。 -Strict Mode lets you notice such mistakes early in the process. When you fix your Effect by adding a cleanup function in Strict Mode, you *also* fix many possible future production bugs like the select box from before: +严格模式让你能够在开发过程的早期就发现这样的错误。当你在严格模式下通过添加清理函数来修复你的 Effect 时,你也同时修复了许多可能在未来的生产环境中出现的错误,比如之前的下拉框问题。 @@ -754,27 +753,27 @@ function ChatRoom({ roomId }) { return () => connection.disconnect(); }, [roomId]); - return

          Welcome to the {roomId} room!

          ; + return

          欢迎来到 {roomId} 聊天室!

          ; } export default function App() { - const [roomId, setRoomId] = useState('general'); + const [roomId, setRoomId] = useState('所有'); const [show, setShow] = useState(false); return ( <> {show &&
          } {show && } @@ -787,17 +786,17 @@ export default function App() { let connections = 0; export function createConnection(serverUrl, roomId) { - // A real implementation would actually connect to the server + // 实际的实现将会连接到服务器 return { connect() { - console.log('✅ Connecting to "' + roomId + '" room at ' + serverUrl + '...'); + console.log('✅ 连接到 "' + roomId + '" 聊天室,位于' + serverUrl + '...'); connections++; - console.log('Active connections: ' + connections); + console.log('活跃连接数: ' + connections); }, disconnect() { - console.log('❌ Disconnected from "' + roomId + '" room at ' + serverUrl); + console.log('❌ 断开 "' + roomId + '" 聊天室,位于' + serverUrl); connections--; - console.log('Active connections: ' + connections); + console.log('活跃连接数: ' + connections); } }; } @@ -810,21 +809,21 @@ button { margin-left: 10px; }
          -Notice how the active connection count in the console doesn't keep growing anymore. +请注意,控制台中活跃连接的数量不再持续增加。 -Without Strict Mode, it was easy to miss that your Effect needed cleanup. By running *setup → cleanup → setup* instead of *setup* for your Effect in development, Strict Mode made the missing cleanup logic more noticeable. +在没有严格模式的情况下,很容易忽视你的 Effect 需要进行清理的情况。通过在开发中运行 *setup → cleanup → setup*,而不是仅运行 *setup*,严格模式使缺失的 cleanup 逻辑更加直观。 -[Read more about implementing Effect cleanup.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development) +[请阅读更多关于实现 Effect 清理的内容](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development)。 --- -### Fixing deprecation warnings enabled by Strict Mode {/*fixing-deprecation-warnings-enabled-by-strict-mode*/} +### 修复严格模式发出的弃用警告 {/*fixing-deprecation-warnings-enabled-by-strict-mode*/} -React warns if some component anywhere inside a `` tree uses one of these deprecated APIs: +React 会在任何一个位于 `` 树中的组件使用以下弃用 API 时发出警告: -* [`findDOMNode`](/reference/react-dom/findDOMNode). [See alternatives.](https://reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage) -* `UNSAFE_` class lifecycle methods like [`UNSAFE_componentWillMount`](/reference/react/Component#unsafe_componentwillmount). [See alternatives.](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#migrating-from-legacy-lifecycles) -* Legacy context ([`childContextTypes`](/reference/react/Component#static-childcontexttypes), [`contextTypes`](/reference/react/Component#static-contexttypes), and [`getChildContext`](/reference/react/Component#getchildcontext)). [See alternatives.](/reference/react/createContext) -* Legacy string refs ([`this.refs`](/reference/react/Component#refs)). [See alternatives.](https://reactjs.org/docs/strict-mode.html#warning-about-legacy-string-ref-api-usage) +* [`findDOMNode`](/reference/react-dom/findDOMNode),[请参考替代方案](https://reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage)。 +* `UNSAFE_` 类生命周期方法,例如 [`UNSAFE_componentWillMount`](/reference/react/Component#unsafe_componentwillmount),[请参考替代方案](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#migrating-from-legacy-lifecycles)。 +* 旧版上下文([`childContextTypes`](/reference/react/Component#static-childcontexttypes)、[`contextTypes`](/reference/react/Component#static-contexttypes) 和 [`getChildContext`](/reference/react/Component#getchildcontext)),[请参考替代方案](/reference/react/createContext)。 +* 旧版字符串引用([`this.refs`](/reference/react/Component#refs)),[请参考替代方案](https://reactjs.org/docs/strict-mode.html#warning-about-legacy-string-ref-api-usage)。 -These APIs are primarily used in older [class components](/reference/react/Component) so they rarely appear in modern apps. +这些 API 主要用于旧版的[类组件](/reference/react/Component),因此在新版程序中很少出现。 From 659ac4ff9fcf7c451d25bfaf4dfa9d335b92896e Mon Sep 17 00:00:00 2001 From: Xavi Lee Date: Mon, 5 Jun 2023 13:46:25 +0800 Subject: [PATCH 2/7] Update src/content/reference/react/StrictMode.md --- src/content/reference/react/StrictMode.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content/reference/react/StrictMode.md b/src/content/reference/react/StrictMode.md index 88e619d4b2..ac41974177 100644 --- a/src/content/reference/react/StrictMode.md +++ b/src/content/reference/react/StrictMode.md @@ -62,6 +62,7 @@ root.render( 严格模式为 `` 组件内的整个组件树启用额外的开发环境检查,这些检查有助于在开发过程中尽早地发现组件中的常见错误。 + 如果要为整个应用启用严格模式,请在渲染根组件时使用 `` 包裹它: ```js {6,8} From ad812586e403636a6c3b5049883bbfc85cfa2078 Mon Sep 17 00:00:00 2001 From: Yucohny <79147654+Yucohny@users.noreply.github.com> Date: Mon, 19 Jun 2023 13:58:13 +0800 Subject: [PATCH 3/7] Update src/content/reference/react/StrictMode.md Co-authored-by: Xavi Lee --- src/content/reference/react/StrictMode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/StrictMode.md b/src/content/reference/react/StrictMode.md index ac41974177..271689c83d 100644 --- a/src/content/reference/react/StrictMode.md +++ b/src/content/reference/react/StrictMode.md @@ -129,7 +129,7 @@ function App() { 违反此规则的组件会表现得不可预测,并引发错误。为了帮助你找到意外的非纯代码,严格模式**在开发环境中会调用一些函数两次**(仅限应为纯函数的函数)。这些函数包括: - 组件函数体(仅限顶层逻辑,不包括事件处理程序内的代码) -- 传递给 [`useState`](/reference/react/useState)、[`set 函数`](/reference/react/useState#setstate)、[`useMemo`](/reference/react/useMemo) 或 [`useReducer`](/reference/react/useReducer) 的函数。 +- 传递给 [`useState`](/reference/react/useState)、[`set` 函数](/reference/react/useState#setstate)、[`useMemo`](/reference/react/useMemo) 或 [`useReducer`](/reference/react/useReducer) 的函数。 - 部分类组件的方法,例如 [`constructor`](/reference/react/Component#constructor)、[`render`](/reference/react/Component#render)、[`shouldComponentUpdate`](/reference/react/Component#shouldcomponentupdate) 等([请参阅完整列表](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects))。 如果一个函数是纯函数,运行两次不会改变其行为,因为纯函数每次都会产生相同的结果。然而,如果一个函数是非纯函数(例如,它会修改接收到的数据),运行两次通常会产生明显的差异(这就是它是非纯函数的原因!)。这有助于您及早发现并修复错误。 From 31444ccafce27a61abbe5c26f04bbdb709f24aa5 Mon Sep 17 00:00:00 2001 From: Yucohny <79147654+Yucohny@users.noreply.github.com> Date: Mon, 19 Jun 2023 14:04:01 +0800 Subject: [PATCH 4/7] Update StrictMode.md --- src/content/reference/react/StrictMode.md | 48 +++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/content/reference/react/StrictMode.md b/src/content/reference/react/StrictMode.md index 271689c83d..0edbc54bed 100644 --- a/src/content/reference/react/StrictMode.md +++ b/src/content/reference/react/StrictMode.md @@ -43,8 +43,8 @@ root.render( 严格模式启用了以下仅在开发环境下有效的行为: - 组件将 [重新渲染一次](#fixing-bugs-found-by-double-rendering-in-development),以查找由于非纯渲染而引起的错误。 -- 组件将 [重新运行 Effects 一次](#fixing-bugs-found-by-re-running-effects-in-development),以查找由于缺少 Effect 清理而引起的错误。 -- 组件将被[检查是否使用了已弃用的 API](#fixing-deprecation-warnings-enabled-by-strict-mode)。 +- 组件将 [重新运行 Effect 一次](#fixing-bugs-found-by-re-running-effects-in-development),以查找由于缺少 Effect 清理而引起的错误。 +- 组件将被 [检查是否使用了已弃用的 API](#fixing-deprecation-warnings-enabled-by-strict-mode)。 #### 参数 {/*props*/} @@ -79,15 +79,15 @@ root.render( 我们建议将整个应用程序包裹在严格模式中,特别是对于新创建的应用程序。如果你使用的是一个调用 [`createRoot`](/reference/react-dom/client/createRoot) 的框架,请查阅其文档以了解如何启用严格模式。 -尽管严格模式的检查**仅在开发环境**下运行,但它们有助于找出已经存在于代码中但在生产环境中可能难以复现的错误。严格模式让你在用户反馈之前就可以修复这些错误。 +尽管严格模式的检查 **仅在开发环境** 下运行,但它们有助于找出已经存在于代码中但在生产环境中可能难以复现的错误。严格模式让你在用户反馈之前就可以修复这些错误。 严格模式启用了以下仅在开发环境下有效的行为: - 组件将 [重新渲染一次](#fixing-bugs-found-by-double-rendering-in-development),以查找由于非纯渲染而引起的错误。 -- 组件将 [重新运行 Effects 一次](#fixing-bugs-found-by-re-running-effects-in-development),以查找由于缺少 Effect 清理而引起的错误。 -- 组件将被[检查是否使用了已弃用的 API](#fixing-deprecation-warnings-enabled-by-strict-mode)。 +- 组件将 [重新运行 Effect 一次](#fixing-bugs-found-by-re-running-effects-in-development),以查找由于缺少 Effect 清理而引起的错误。 +- 组件将被 [检查是否使用了已弃用的 API](#fixing-deprecation-warnings-enabled-by-strict-mode)。 **所有这些检查仅在开发环境中进行,不会影响生产构建。** @@ -124,19 +124,19 @@ function App() { ### 修复在开发过程中通过双重渲染发现的错误 {/*fixing-bugs-found-by-double-rendering-in-development*/} -[React假设您编写的每个组件都是纯函数](/learn/keeping-components-pure)。这意味着您编写的 React 组件在给定相同的输入(props、state 和 context)时必须始终返回相同的 JSX。 +[React 假设编写的每个组件都是纯函数](/learn/keeping-components-pure)。这意味着编写的 React 组件在给定相同的输入(props、state 和 context)时必须始终返回相同的 JSX。 -违反此规则的组件会表现得不可预测,并引发错误。为了帮助你找到意外的非纯代码,严格模式**在开发环境中会调用一些函数两次**(仅限应为纯函数的函数)。这些函数包括: +违反此规则的组件会表现得不可预测,并引发错误。为了帮助你找到意外的非纯函数代码,严格模式 **在开发环境中会调用一些函数两次**(仅限应为纯函数的函数)。这些函数包括: - 组件函数体(仅限顶层逻辑,不包括事件处理程序内的代码) - 传递给 [`useState`](/reference/react/useState)、[`set` 函数](/reference/react/useState#setstate)、[`useMemo`](/reference/react/useMemo) 或 [`useReducer`](/reference/react/useReducer) 的函数。 -- 部分类组件的方法,例如 [`constructor`](/reference/react/Component#constructor)、[`render`](/reference/react/Component#render)、[`shouldComponentUpdate`](/reference/react/Component#shouldcomponentupdate) 等([请参阅完整列表](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects))。 +- 部分类组件的方法,例如 [`constructor`](/reference/react/Component#constructor)、[`render`](/reference/react/Component#render)、[`shouldComponentUpdate`](/reference/react/Component#shouldcomponentupdate) 等([请参阅完整列表](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects))。 -如果一个函数是纯函数,运行两次不会改变其行为,因为纯函数每次都会产生相同的结果。然而,如果一个函数是非纯函数(例如,它会修改接收到的数据),运行两次通常会产生明显的差异(这就是它是非纯函数的原因!)。这有助于您及早发现并修复错误。 +如果一个函数是纯函数,运行两次不会改变其行为,因为纯函数每次都会产生相同的结果。然而,如果一个函数是非纯函数(例如,它会修改接收到的数据),运行两次通常会产生明显的差异(这就是它是非纯函数的原因!)。这有助于及早发现并修复错误。 **下面是一个示例,用来说明严格模式中的双重渲染如何帮助你早期发现错误**。 -这个 `StoryTray` 组件接收一个 `stories` 数组,并在末尾添加一个额外的“创建故事”节点: +下面的 `StoryTray` 组件接收一个 `stories` 数组,并在末尾添加一个额外的“创建故事”节点: @@ -214,7 +214,7 @@ li { 上面的代码中有一个错误,但很容易忽视,因为初始输出看起来是正确的。 -如果 `StoryTray` 组件重新渲染多次,这个错误将变得更加明显。例如,让我们在鼠标悬停在 `StoryTray` 组件上时,以不同的背景颜色重新渲染它: +如果 `StoryTray` 组件重新渲染多次,这个错误将变得更加明显。例如,当鼠标悬停在 `StoryTray` 组件上时,以不同的背景颜色重新渲染它: @@ -310,9 +310,9 @@ export default function StoryTray({ stories }) { items.push({ id: 'create', label: 'Create Story' }); ``` -这样做会[使 `StoryTray` 函数成为纯函数](/learn/keeping-components-pure)。每次调用函数时,它只会修改一个新的数组副本,不会影响任何外部对象或变量。这解决了错误,但在发现其行为有问题之前,你可能需要更频繁地使组件重新渲染。 +这样做会 [使 `StoryTray` 函数成为纯函数](/learn/keeping-components-pure)。每次调用函数时,它只会修改一个新的数组副本,不会影响任何外部对象或变量。这解决了错误,但在发现其行为有问题之前,你可能需要更频繁地使组件重新渲染。 -**在原始的例子中,这个错误并不明显。现在让我们将原始有错误的代码包裹在 `` 中:** +**在原始的例子中,这个错误并不明显。现在让我们将原始有错误的代码包裹在 `` 中**: @@ -393,7 +393,7 @@ li { -**严格模式*始终*会调用您的渲染函数两次**,这样您就可以立即发现错误(“创建故事”出现两次)。这让您能够在早期阶段注意到此类错误。当您修复组件以在严格模式下进行渲染时,您也会修复许多可能的未来生产错误,例如之前的悬停功能: +**严格模式始终会调用渲染函数两次**,这样可以帮助立即发现错误(“创建故事”出现两次)。这让开发者能够在早期阶段注意到此类错误。当修复组件以在严格模式下进行渲染时,也会修复许多可能的未来生产错误,例如之前的悬停功能: @@ -485,25 +485,25 @@ li { 在没有严格模式的情况下,在你添加了更多的重新渲染前很容易忽视这个错误。而严格模式立即显示了相同的错误。严格模式可以帮助你在将错误推送给团队和用户之前发现它们。 -[更多请阅读保持组件纯粹](/learn/keeping-components-pure)。 +[更多请阅读《保持组件纯粹》](/learn/keeping-components-pure)。 -如果您已经安装了 [React DevTools](/learn/react-developer-tools),在第二次渲染期间进行的任何 `console.log` 调用将会显示为稍微变暗的颜色。React DevTools 还提供了一个设置(默认情况下关闭),可以完全禁止显示这些日志。 +如果你已经安装了 [React DevTools](/learn/react-developer-tools),在第二次渲染期间进行的任何 `console.log` 调用将会显示为稍微变暗的颜色。React DevTools 还提供了一个设置(默认情况下关闭),可以完全禁止显示这些日志。 --- -### 修复在开发中通过重新运行 Effects 发现的错误 {/*fixing-bugs-found-by-re-running-effects-in-development*/} +### 修复在开发中通过重新运行 Effect 发现的错误 {/*fixing-bugs-found-by-re-running-effects-in-development*/} -严格模式也可以帮助发现 [Effects](/learn/synchronizing-with-effects) 中的错误。 +严格模式也可以帮助发现 [Effect](/learn/synchronizing-with-effects) 中的错误。 -每个 Effect 都有一些 setup 和可能的 cleanup 。通常情况下,当组件*挂载*(添加到屏幕)时,React 会调用设置代码,当组件*卸载*(从屏幕移除)时,React 会调用清理代码。如果依赖关系在上一次渲染之后发生了变化,React 将再次调用清理代码和设置代码。 +每个 Effect 都有一些 setup 和可能的 cleanup 函数。通常情况下,当组件挂载时,React 会调用 setup 代码;当组件卸载时,React 会调用 cleanup 代码。如果依赖关系在上一次渲染之后发生了变化,React 将再次调用 setup 代码和 cleanup 代码。 -当开启严格模式时,React 还会在开发模式下为每个 Effect **额外运行一次setup 和 cleanup**。这可能会让人感到惊讶,但它有助于发现手动难以捕捉到的细微错误。 +当开启严格模式时,React 还会在开发模式下为每个 Effect **额外运行一次 setup 和 cleanup 函数**。这可能会让人感到惊讶,但它有助于发现手动难以捕捉到的细微错误。 -**下面是一个例子,用来说明在严格模式下重新运行 Effects 如何帮助您早期发现错误。** +**下面是一个例子,用来说明在严格模式下重新运行 Effects 如何帮助您早期发现错误**。 参考以下将组件连接到聊天功能的示例: @@ -646,7 +646,7 @@ button { margin-left: 10px; } -你会注意到打开的连接数量一直在增加。在真实的应用程序中,这会导致性能和网络问题。问题出在[你的 Effect 缺少清理函数](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed): +你会注意到打开的连接数量一直在增加。在真实的应用程序中,这会导致性能和网络问题。问题出在 [你的 Effect 缺少 cleanup 函数](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed): ```js {4} useEffect(() => { @@ -658,7 +658,7 @@ button { margin-left: 10px; } 现在你的 Effect 在自身执行清理并销毁过时的连接后,问题被解决了。但是请注意,在添加了更多功能(下拉框)之前,这个问题很难被发现。 -**在原始的例子中,这个错误并不明显。现在让我们将原始有错误的代码包裹在 `` 中:** +**在原始的例子中,这个错误并不明显。现在让我们将原始有错误的代码包裹在 `` 中**: @@ -827,4 +827,4 @@ React 会在任何一个位于 `` 树中的组件使用以下弃用 * 旧版上下文([`childContextTypes`](/reference/react/Component#static-childcontexttypes)、[`contextTypes`](/reference/react/Component#static-contexttypes) 和 [`getChildContext`](/reference/react/Component#getchildcontext)),[请参考替代方案](/reference/react/createContext)。 * 旧版字符串引用([`this.refs`](/reference/react/Component#refs)),[请参考替代方案](https://reactjs.org/docs/strict-mode.html#warning-about-legacy-string-ref-api-usage)。 -这些 API 主要用于旧版的[类组件](/reference/react/Component),因此在新版程序中很少出现。 +这些 API 主要用于旧版的 [类式组件](/reference/react/Component),因此在新版程序中很少出现。 From 69148caad1c019c350fe3251f3fe952e8bc59d2d Mon Sep 17 00:00:00 2001 From: Yucohny <79147654+Yucohny@users.noreply.github.com> Date: Tue, 20 Jun 2023 00:27:31 +0800 Subject: [PATCH 5/7] Update src/content/reference/react/StrictMode.md Co-authored-by: Xleine <919143384@qq.com> --- src/content/reference/react/StrictMode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/StrictMode.md b/src/content/reference/react/StrictMode.md index 0edbc54bed..271a0aa1c6 100644 --- a/src/content/reference/react/StrictMode.md +++ b/src/content/reference/react/StrictMode.md @@ -52,7 +52,7 @@ root.render( #### 注意事项 {/*caveats*/} -* 在由 `` 包裹的树中,无法选择退出严格模式。这可以确保在 `` 内的所有组件都经过检查。如果两个团队在一个产品上工作,对于是否认为这些检查有价值存在分歧,他们需要达成共识或将 `` 下移到树的较低层级。 +* 在由 `` 包裹的树中,无法选择退出严格模式。这可以确保在 `` 内的所有组件都经过检查。如果两个团队在一个产品上工作,并且对于这些检查是否有价值存在分歧,他们需要达成共识或将 `` 下移到树的较低层级。 --- From ffc277c42e26a1a8d7314df720be314354a8a993 Mon Sep 17 00:00:00 2001 From: Yucohny <79147654+Yucohny@users.noreply.github.com> Date: Tue, 20 Jun 2023 00:27:37 +0800 Subject: [PATCH 6/7] Update src/content/reference/react/StrictMode.md Co-authored-by: Xleine <919143384@qq.com> --- src/content/reference/react/StrictMode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/StrictMode.md b/src/content/reference/react/StrictMode.md index 271a0aa1c6..998510aee0 100644 --- a/src/content/reference/react/StrictMode.md +++ b/src/content/reference/react/StrictMode.md @@ -212,7 +212,7 @@ li { -上面的代码中有一个错误,但很容易忽视,因为初始输出看起来是正确的。 +上面的代码中有一个错误,但很容易被忽视,因为初始输出看起来是正确的。 如果 `StoryTray` 组件重新渲染多次,这个错误将变得更加明显。例如,当鼠标悬停在 `StoryTray` 组件上时,以不同的背景颜色重新渲染它: From 2dbe2ac8b97cd5a057dc361750970d3ea5b01b1f Mon Sep 17 00:00:00 2001 From: Yucohny <79147654+Yucohny@users.noreply.github.com> Date: Tue, 20 Jun 2023 00:28:25 +0800 Subject: [PATCH 7/7] Update src/content/reference/react/StrictMode.md Co-authored-by: Xleine <919143384@qq.com> --- src/content/reference/react/StrictMode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/StrictMode.md b/src/content/reference/react/StrictMode.md index 998510aee0..535033720a 100644 --- a/src/content/reference/react/StrictMode.md +++ b/src/content/reference/react/StrictMode.md @@ -812,7 +812,7 @@ button { margin-left: 10px; } 请注意,控制台中活跃连接的数量不再持续增加。 -在没有严格模式的情况下,很容易忽视你的 Effect 需要进行清理的情况。通过在开发中运行 *setup → cleanup → setup*,而不是仅运行 *setup*,严格模式使缺失的 cleanup 逻辑更加直观。 +在没有严格模式的情况下,很容易忽视你的 Effect 需要进行清理的情况。通过在开发中运行 *setup → cleanup → setup*,而不是仅运行 *setup*,严格模式使你更容易发现遗漏的 cleanup 逻辑。 [请阅读更多关于实现 Effect 清理的内容](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development)。