Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(cn): translate warnings/invalid-hook-call-warning to Chinese #1153

Merged
merged 25 commits into from
Jun 29, 2023
Merged
Changes from 6 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
69ffda8
docs(cn): translate warnings/invalid-hook-call-warning to Chinese
JohnhanLiu May 4, 2023
20593b7
Merge branch 'main' into translations
JohnhanLiu May 4, 2023
c758386
docs(cn): translate title of article
JohnhanLiu May 4, 2023
e7fc561
docs(cn): remove a duplicate word
JohnhanLiu May 6, 2023
01aeff9
Merge branch 'reactjs:main' into translations
JohnhanLiu Jun 26, 2023
2c53ab7
docs(cn): translate warnings/invalid-hook-call-warning to Chinese
JohnhanLiu Jun 26, 2023
fa1dbb0
Merge branch 'main' into translations
Yucohny Jun 28, 2023
7549619
docs(cn): translate warnings/invalid-hook-call-warning to Chinese
JohnhanLiu Jun 28, 2023
503e6cf
Merge branch 'main' into translations
Yucohny Jun 29, 2023
e673f2d
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
dec7f36
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
453977f
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
f1b8ffe
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
0e62647
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
0262899
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
a1dc38a
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
70f59cb
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
dfd40fe
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
aeee7c7
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
5e0bc2d
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
1cb577c
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
389a1c7
Update src/content/warnings/invalid-hook-call-warning.md
Yucohny Jun 29, 2023
3a76ada
docs(cn): review and update
Yucohny Jun 29, 2023
b335aa5
docs(cn): review and update
Yucohny Jun 29, 2023
a6d5080
Merge branch 'main' into translations
Yucohny Jun 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 44 additions & 44 deletions src/content/warnings/invalid-hook-call-warning.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
---
title: Rules of Hooks
title: Hooks 的规则
JohnhanLiu marked this conversation as resolved.
Show resolved Hide resolved
---

You are probably here because you got the following error message:
你进入到这个页面,大概是因为遇到了下面这个错误提示:

<ConsoleBlock level="error">

Hooks can only be called inside the body of a function component.

</ConsoleBlock>

There are three common reasons you might be seeing it:
这个错误原因,通常有以下3个:
JohnhanLiu marked this conversation as resolved.
Show resolved Hide resolved

1. You might be **breaking the Rules of Hooks**.
2. You might have **mismatching versions** of React and React DOM.
3. You might have **more than one copy of React** in the same app.
1. 你可能 **打破了 Hooks 的使用规则**。
2. 你可能使用了 **版本不一致** React React DOM
3. 你可能在同一个应用当中使用了 **重复的 React 引用**。

Let's look at each of these cases.
让我们来逐个看看这些问题。

## Breaking Rules of Hooks {/*breaking-rules-of-hooks*/}
## 打破了 Hooks 的使用规则 {/*breaking-rules-of-hooks*/}

Functions whose names start with `use` are called [*Hooks*](/reference/react) in React.
在 React 中被调用的且以 `use` 开头命名的函数叫 [*Hooks*](/reference/react)

**Don’t call Hooks inside loops, conditions, or nested functions.** Instead, always use Hooks at the top level of your React function, before any early returns. You can only call Hooks while React is rendering a function component:
**不要在循环语句内、条件语句后或嵌套的函数内调用 Hooks**。 反之,应该始终保证 Hooks 在函数式组件的顶层,并避免在 Hooks 调用前过早终止函数。你只能在 React 渲染一个函数式组件的过程当中调用 Hooks:

* ✅ Call them at the top level in the body of a [function component](/learn/your-first-component).
* ✅ Call them at the top level in the body of a [custom Hook](/learn/reusing-logic-with-custom-hooks).
* ✅ 在 [函数式组件](/learn/your-first-component) 内部的顶级作用域调用他们。
* ✅ 在 [自定义 Hook](/learn/reusing-logic-with-custom-hooks) 内部的顶级作用域调用他们。

```js{2-3,8-9}
function Counter() {
// ✅ Good: top-level in a function component
// ✅ 正确:函数式组件的顶级作用域
const [count, setCount] = useState(0);
// ...
}

function useWindowWidth() {
// ✅ Good: top-level in a custom Hook
// ✅ 正确:自定义 Hook 的顶级作用域
const [width, setWidth] = useState(window.innerWidth);
// ...
}
```

It’s **not** supported to call Hooks (functions starting with `use`) in any other cases, for example:
以下有几个要点,这些情况下 **** 支持调用 Hooks (以 `use` 开头的函数),例如:

* 🔴 Do not call Hooks inside conditions or loops.
* 🔴 Do not call Hooks after a conditional `return` statement.
* 🔴 Do not call Hooks in event handlers.
* 🔴 Do not call Hooks in class components.
* 🔴 Do not call Hooks inside functions passed to `useMemo`, `useReducer`, or `useEffect`.
* 🔴 不要在条件语句内或循环语句内调用 Hooks
* 🔴 不要在包含 `return` 的条件语句之后调用 Hooks
* 🔴 不要在事件监听器或回调中调用 Hooks
* 🔴 不要在类式组件内调用 Hooks
* 🔴 不要在那些传给 `useMemo``useReducer` `useEffect` 的函数内调用 Hooks

If you break these rules, you might see this error.
如果你打破了这些规则,你就会可能看到这个错误提示。
Yucohny marked this conversation as resolved.
Show resolved Hide resolved

```js{3-4,11-12,20-21}
function Bad({ cond }) {
if (cond) {
// 🔴 Bad: inside a condition (to fix, move it outside!)
// 🔴 错误: 在条件语句内调用 (修复办法:把它挪到外层!)
Yucohny marked this conversation as resolved.
Show resolved Hide resolved
const theme = useContext(ThemeContext);
}
// ...
}

function Bad() {
for (let i = 0; i < 10; i++) {
// 🔴 Bad: inside a loop (to fix, move it outside!)
// 🔴 错误: 在循环内调用 (修复办法:把它挪到外层!)
const theme = useContext(ThemeContext);
}
// ...
Expand All @@ -72,22 +72,22 @@ function Bad({ cond }) {
if (cond) {
return;
}
// 🔴 Bad: after a conditional return (to fix, move it before the return!)
// 🔴 错误: 在一个包含return的条件语句后调用 (修复办法:挪到return之前!)
const theme = useContext(ThemeContext);
// ...
}

function Bad() {
function handleClick() {
// 🔴 Bad: inside an event handler (to fix, move it outside!)
// 🔴 错误: 在事件监听器或回调中调用 (修复办法:把它挪到外层!)
const theme = useContext(ThemeContext);
}
// ...
}

function Bad() {
const style = useMemo(() => {
// 🔴 Bad: inside useMemo (to fix, move it outside!)
// 🔴 错误: 在 useMemo 内调用 (修复办法:把它挪到外层!)
const theme = useContext(ThemeContext);
return createStyle(theme);
});
Expand All @@ -96,63 +96,63 @@ function Bad() {

class Bad extends React.Component {
render() {
// 🔴 Bad: inside a class component (to fix, write a function component instead of a class!)
// 🔴 错误: 在类式组件内调用 (修复办法:写一个函数式组件而不是类式组件!)
useEffect(() => {})
// ...
}
}
```

You can use the [`eslint-plugin-react-hooks` plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) to catch these mistakes.
你可以借助 [`eslint-plugin-react-hooks` 插件](https://www.npmjs.com/package/eslint-plugin-react-hooks) 来帮你提前暴露这些错误。

<Note>

[Custom Hooks](/learn/reusing-logic-with-custom-hooks) *may* call other Hooks (that's their whole purpose). This works because custom Hooks are also supposed to only be called while a function component is rendering.
[自定义 Hook](/learn/reusing-logic-with-custom-hooks) **可能** 被其他的 Hook 调用 (这仍然符合设计初衷)。为什么呢?因为自定义 Hooks 也是被设定为只能在函数式组件渲染过程中被调用。

</Note>

## Mismatching Versions of React and React DOM {/*mismatching-versions-of-react-and-react-dom*/}
## 版本不一致的 React React DOM {/*mismatching-versions-of-react-and-react-dom*/}

You might be using a version of `react-dom` (< 16.8.0) or `react-native` (< 0.59) that doesn't yet support Hooks. You can run `npm ls react-dom` or `npm ls react-native` in your application folder to check which version you're using. If you find more than one of them, this might also create problems (more on that below).
你可能正在使用一个还不支持 Hooks 的版本,例如 `react-dom` (< 16.8.0) `react-native` (< 0.59)。你可以在你的应用目录下执行 `npm ls react-dom` `npm ls react-native` 来检查下你正在使用的版本。如果你发现了同一个包有多个版本,那也可能带来其他的问题(下文会详细展开)。

## Duplicate React {/*duplicate-react*/}
## 重复的 React {/*duplicate-react*/}

In order for Hooks to work, the `react` import from your application code needs to resolve to the same module as the `react` import from inside the `react-dom` package.
为了使 Hooks 正常工作,你需要确保你应用代码中所引用的 `react` `react-dom` 内部使用的 `react` 是同一个来源。

If these `react` imports resolve to two different exports objects, you will see this warning. This may happen if you **accidentally end up with two copies** of the `react` package.
如果上述的两个 `react` 是使用不同模块导出的值,你可能会看到这个警告信息。一般来说,原因都会是你 **意外地使用了重复的** `react` 包。

If you use Node for package management, you can run this check in your project folder:
如果你用的是 Node 做包管理,你可以在你的应用目录下执行这个命令做个检查:

<TerminalBlock>

npm ls react

</TerminalBlock>

If you see more than one React, you'll need to figure out why this happens and fix your dependency tree. For example, maybe a library you're using incorrectly specifies `react` as a dependency (rather than a peer dependency). Until that library is fixed, [Yarn resolutions](https://yarnpkg.com/lang/en/docs/selective-version-resolutions/) is one possible workaround.
如果你看到了超过1个 `React`,你可能需要去搞明白为什么会这样,并且修复一下你的包依赖关系。举个例子:你可能用了一个包,其内部错误地声明了 `react` 作为它的依赖(推荐做法应该是在 peerDependency 中)。在这个包被修复之前, [Yarn resolutions](https://yarnpkg.com/lang/en/docs/selective-version-resolutions/) 可以作为一个临时解决办法。

You can also try to debug this problem by adding some logs and restarting your development server:
你也可以通过增加一些日志,然后重启你的开发服务器,这样你就可以自己来调试这个问题了:

```js
// Add this in node_modules/react-dom/index.js
// 把下面这行加在 node_modules/react-dom/index.js
window.React1 = require('react');

// Add this in your component file
// 把下面这几行加入到你的组件逻辑中
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2);
```

If it prints `false` then you might have two Reacts and need to figure out why that happened. [This issue](https://github.com/facebook/react/issues/13991) includes some common reasons encountered by the community.
如果你在控制台看到打印了 `false`,那代表你的项目中存在两个 React,你需要搞明白这是为什么。[这个 GitHub 问题](https://github.com/facebook/react/issues/13991) 里列举了一些常见的可能的原因。
Yucohny marked this conversation as resolved.
Show resolved Hide resolved

This problem can also come up when you use `npm link` or an equivalent. In that case, your bundler might "see" two Reacts — one in application folder and one in your library folder. Assuming `myapp` and `mylib` are sibling folders, one possible fix is to run `npm link ../myapp/node_modules/react` from `mylib`. This should make the library use the application's React copy.
如果你使用了 `npm link` 或者同类操作,也有可能导致这个问题出现。在这种情况下,你的构建工具可能会“看到”两个不同的 React —— 一个在应用目录,另一个则在工具库的目录。假设 `myapp` `mylib` 是两个相邻的目录,一个可能有效的解决办法是在 `mylib` 目录下执行 `npm link ../myapp/node_modules/react`,这样就能让工具库里面使用的 React 和你应用里面使用的是同一个了。

<Note>

In general, React supports using multiple independent copies on one page (for example, if an app and a third-party widget both use it). It only breaks if `require('react')` resolves differently between the component and the `react-dom` copy it was rendered with.
通常来讲,在一个页面上使用多个相互独立的 React 是完全没问题的(举个例子,应用和第三方库同时使用各自的 React)。只有当你组件里引用的 `react` 和 `react-dom` 里引用的 `react` 不一致时,才会导致这个报错。

</Note>

## Other Causes {/*other-causes*/}
## 其他的原因 {/*other-causes*/}

If none of this worked, please comment in [this issue](https://github.com/facebook/react/issues/13991) and we'll try to help. Try to create a small reproducing example — you might discover the problem as you're doing it.
如果上文没有解决你的问题,你可以在 [这个 GitHub 问题](https://github.com/facebook/react/issues/13991) 中做评论,我们会积极地提供帮助。评论的时候,如果能提供一个小的、能复现的示例那最好不过了。
Yucohny marked this conversation as resolved.
Show resolved Hide resolved