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 content/docs/hooks-rules.md into Chinese #135

Merged
merged 21 commits into from
Mar 20, 2019
Merged
Changes from all commits
Commits
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
48 changes: 24 additions & 24 deletions content/docs/hooks-rules.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
---
id: hooks-rules
title: Rules of Hooks
title: 使用 Hook 的规则
permalink: docs/hooks-rules.html
next: hooks-custom.html
prev: hooks-effect.html
---

*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class.
*Hook* 是 React 16.8 的新增特性。它可以让你在不使用 class 的情况下使用 state 和一些其他 React 特性。

Hooks are JavaScript functions, but you need to follow two rules when using them. We provide a [linter plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) to enforce these rules automatically:
Hook 本质就是 JavaScript 函数,但是在使用它时需要遵循两条规则。我们提供了一个 [linter 插件](https://www.npmjs.com/package/eslint-plugin-react-hooks)来强制执行这些规则:

### Only Call Hooks at the Top Level {#only-call-hooks-at-the-top-level}
### 只在最顶层使用 Hook {#only-call-hooks-at-the-top-level}

**Don't call Hooks inside loops, conditions, or nested functions.** Instead, always use Hooks at the top level of your React function. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That's what allows React to correctly preserve the state of Hooks between multiple `useState` and `useEffect` calls. (If you're curious, we'll explain this in depth [below](#explanation).)
**不要在循环,条件或嵌套函数中调用 Hook,**确保总是在你的 React 函数的最顶层调用他们。遵守这条规则,你就能确保 Hook 在每一次渲染中都按照同样的顺序被调用。这让 React 能够在多次的 `useState` `useEffect` 调用之间保持 hook 状态的正确。(如果你对此感到好奇,我们在[下面](#explanation)会有更深入的解释。)

### Only Call Hooks from React Functions {#only-call-hooks-from-react-functions}
### 只在 React 函数中调用 Hook {#only-call-hooks-from-react-functions}

**Don't call Hooks from regular JavaScript functions.** Instead, you can:
**不要在普通的 JavaScript 函数中调用 Hook。**你可以:

* ✅ Call Hooks from React function components.
* ✅ Call Hooks from custom Hooks (we'll learn about them [on the next page](/docs/hooks-custom.html)).
* ✅ React 的函数组件中调用 Hook
* ✅ 在自定义 Hook 中调用其他 Hook (我们将会在[下一页](/docs/hooks-custom.html) 中学习这个。)

By following this rule, you ensure that all stateful logic in a component is clearly visible from its source code.
遵循此规则,确保组件的状态逻辑在代码中清晰可见。

## ESLint Plugin {#eslint-plugin}
## ESLint 插件 {#eslint-plugin}

We released an ESLint plugin called [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) that enforces these two rules. You can add this plugin to your project if you'd like to try it:
我们发布了一个名为 [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) 的 ESLint 插件来强制执行这两条规则。如果你想尝试一下,可以将此插件添加到你的项目中:

```bash
npm install eslint-plugin-react-hooks
Expand All @@ -45,13 +45,13 @@ npm install eslint-plugin-react-hooks
}
```

In the future, we intend to include this plugin by default into Create React App and similar toolkits.
我们打算后续版本默认添加此插件到 Create React App 及其他类似的工具包中。

**You can skip to the next page explaining how to write [your own Hooks](/docs/hooks-custom.html) now.** On this page, we'll continue by explaining the reasoning behind these rules.
**现在你可以跳转到下一章节学习如何编写[你自己的 Hook](/docs/hooks-custom.html)。**在本章节中,我们将继续解释这些规则背后的原因。

## Explanation {#explanation}
## 说明 {#explanation}

As we [learned earlier](/docs/hooks-state.html#tip-using-multiple-state-variables), we can use multiple State or Effect Hooks in a single component:
正如我们[之前学到](/docs/hooks-state.html#tip-using-multiple-state-variables)的,我们可以在单个组件中使用多个 State Hook 或 Effect Hook

```js
function Form() {
Expand All @@ -75,7 +75,7 @@ function Form() {
}
```

So how does React know which state corresponds to which `useState` call? The answer is that **React relies on the order in which Hooks are called**. Our example works because the order of the Hook calls is the same on every render:
那么 React 怎么知道哪个 state 对应哪个 `useState`?答案是 React 靠的是 Hook 调用的顺序。因为我们的示例中,Hook 的调用顺序在每次渲染中都是相同的,所以它能够正常工作:

```js
// ------------
Expand All @@ -97,7 +97,7 @@ useEffect(updateTitle) // 4. Replace the effect for updating the title
// ...
```

As long as the order of the Hook calls is the same between renders, React can associate some local state with each of them. But what happens if we put a Hook call (for example, the `persistForm` effect) inside a condition?
只要 Hook 的调用顺序在多次渲染之间保持一致,React 就能正确地将内部 state 和对应的 Hook 关联。但如果我们将一个 Hook (例如 `persistForm` effect) 调用放到一个条件语句中会发生什么呢?

```js
// 🔴 We're breaking the first rule by using a Hook in a condition
Expand All @@ -108,7 +108,7 @@ As long as the order of the Hook calls is the same between renders, React can as
}
```

The `name !== ''` condition is `true` on the first render, so we run this Hook. However, on the next render the user might clear the form, making the condition `false`. Now that we skip this Hook during rendering, the order of the Hook calls becomes different:
在第一次渲染中 `name !== ''` 这个条件值为 `true`,所以我们会执行这个 Hook。但是下一次渲染时我们可能清空了表单,表达式值变为 `false`。此时的渲染会跳过该 HookHook 的调用顺序发生了改变:

```js
useState('Mary') // 1. Read the name state variable (argument is ignored)
Expand All @@ -117,9 +117,9 @@ useState('Poppins') // 🔴 2 (but was 3). Fail to read the surname state
useEffect(updateTitle) // 🔴 3 (but was 4). Fail to replace the effect
```

React wouldn't know what to return for the second `useState` Hook call. React expected that the second Hook call in this component corresponds to the `persistForm` effect, just like during the previous render, but it doesn't anymore. From that point, every next Hook call after the one we skipped would also shift by one, leading to bugs.
React 不知道第二个 `useState` Hook 应该返回什么了。React 以为在这个组件中第二次 Hook 调用像之前的渲染一样,对应了 `persistForm` effect,但事实上并不是。从这里开始,后面的每次 Hook 调用都被移动了一个顺位,导致 bug 的产生。

**This is why Hooks must be called on the top level of our components.** If we want to run an effect conditionally, we can put that condition *inside* our Hook:
**这就是为什么 Hook 需要在我们组件的最顶层调用。**如果我们想要有条件地执行一个 effect,可以将判断放到 Hook 的*内部*:

```js
useEffect(function persistForm() {
Expand All @@ -130,8 +130,8 @@ React wouldn't know what to return for the second `useState` Hook call. React ex
});
```

**Note that you don't need to worry about this problem if you use the [provided lint rule](https://www.npmjs.com/package/eslint-plugin-react-hooks).** But now you also know *why* Hooks work this way, and which issues the rule is preventing.
**注意:如果你使用了[上面提供的 lint 插件](https://www.npmjs.com/package/eslint-plugin-react-hooks),就不需要担心这个问题了。**不过你现在知道了为什么 Hook 会这样工作,也知道了这个规则是为了避免什么问题。

## Next Steps {#next-steps}
## 下一步 {#next-steps}

Finally, we're ready to learn about [writing your own Hooks](/docs/hooks-custom.html)! Custom Hooks let you combine Hooks provided by React into your own abstractions, and reuse common stateful logic between different components.
最后,我们已经准备好学习[如何编写你自己的 Hook](/docs/hooks-custom.html)了!自定义 Hook 允许你将 React 提供的 Hook 组合到您自己的 Hook 中,复用不同组件之间的常见状态逻辑。