diff --git a/content/docs/hooks-rules.md b/content/docs/hooks-rules.md index 698d1c7417..5cdb312787 100644 --- a/content/docs/hooks-rules.md +++ b/content/docs/hooks-rules.md @@ -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 @@ -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() { @@ -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 // ------------ @@ -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 @@ -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`。此时的渲染会跳过该 Hook,Hook 的调用顺序发生了改变: ```js useState('Mary') // 1. Read the name state variable (argument is ignored) @@ -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() { @@ -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 中,复用不同组件之间的常见状态逻辑。