You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: content/docs/hooks-custom.md
+34-34
Original file line number
Diff line number
Diff line change
@@ -1,16 +1,16 @@
1
1
---
2
2
id: hooks-custom
3
-
title: Building Your Own Hooks
3
+
title: 自定义 Hooks
4
4
permalink: docs/hooks-custom.html
5
5
next: hooks-reference.html
6
6
prev: hooks-rules.html
7
7
---
8
8
9
-
*Hooks*are a new addition in React 16.8. They let you use state and other React features without writing a class.
9
+
*Hooks*是 React 16.8 的新增特性,允许你在不编写 class 组件的情况下使用 state 及 React 其他特性。
10
10
11
-
Building your own Hooks lets you extract component logic into reusable functions.
11
+
通过自定义 Hooks,可以将组件逻辑提取到可重用的函数中。
12
12
13
-
When we were learning about [using the Effect Hook](/docs/hooks-effect.html#example-using-hooks-1), we saw this component from a chat application that displays a message indicating whether a friend is online or offline:
import React, { useState, useEffect } from 'react';
@@ -36,7 +36,7 @@ function FriendStatus(props) {
36
36
}
37
37
```
38
38
39
-
Now let's say that our chat application also has a contact list, and we want to render names of online users with a green color. We could copy and paste similar logic above into our `FriendListItem`component but it wouldn't be ideal:
import React, { useState, useEffect } from 'react';
@@ -63,15 +63,15 @@ function FriendListItem(props) {
63
63
}
64
64
```
65
65
66
-
Instead, we'd like to share this logic between `FriendStatus`and`FriendListItem`.
66
+
相反,我们希望在 `FriendStatus`和`FriendListItem` 之间共享逻辑。
67
67
68
-
Traditionally in React, we've had two popular ways to share stateful logic between components: [render props](/docs/render-props.html)and [higher-order components](/docs/higher-order-components.html). We will now look at how Hooks solve many of the same problems without forcing you to add more components to the tree.
## Extracting a Custom Hook {#extracting-a-custom-hook}
70
+
## 提取自定义 Hook {#extracting-a-custom-hook}
71
71
72
-
When we want to share logic between two JavaScript functions, we extract it to a third function. Both components and Hooks are functions, so this works for them too!
**A custom Hook is a JavaScript function whose name starts with "`use`" and that may call other Hooks.**For example, `useFriendStatus`below is our first custom Hook:
import React, { useState, useEffect } from 'react';
@@ -94,11 +94,11 @@ function useFriendStatus(friendID) {
94
94
}
95
95
```
96
96
97
-
There's nothing new inside of it -- the logic is copied from the components above. Just like in a component, make sure to only call other Hooks unconditionally at the top level of your custom Hook.
Unlike a React component, a custom Hook doesn't need to have a specific signature. We can decide what it takes as arguments, and what, if anything, it should return. In other words, it's just like a normal function. Its name should always start with `use`so that you can tell at a glance that the [rules of Hooks](/docs/hooks-rules.html) apply to it.
The purpose of our `useFriendStatus` Hook is to subscribe us to a friend's status. This is why it takes `friendID`as an argument, and returns whether this friend is online:
@@ -110,13 +110,13 @@ function useFriendStatus(friendID) {
110
110
}
111
111
```
112
112
113
-
Now let's see how we can use our custom Hook.
113
+
现在让我们看看应该如何使用自定义 Hook。
114
114
115
-
## Using a Custom Hook {#using-a-custom-hook}
115
+
## 使用自定义 Hook {#using-a-custom-hook}
116
116
117
-
In the beginning, our stated goal was to remove the duplicated logic from the `FriendStatus`and`FriendListItem`components. Both of them want to know whether a friend is online.
@@ -141,19 +141,19 @@ function FriendListItem(props) {
141
141
}
142
142
```
143
143
144
-
**Is this code equivalent to the original examples?** Yes, it works in exactly the same way. If you look closely, you'll notice we didn't make any changes to the behavior. All we did was to extract some common code between two functions into a separate function. **Custom Hooks are a convention that naturally follows from the design of Hooks, rather than a React feature.**
**Do I have to name my custom Hooks starting with “`use`”?** Please do. This convention is very important. Without it, we wouldn't be able to automatically check for violations of [rules of Hooks](/docs/hooks-rules.html) because we couldn't tell if a certain function contains calls to Hooks inside of it.
**Do two components using the same Hook share state?** No. Custom Hooks are a mechanism to reuse *stateful logic* (such as setting up a subscription and remembering the current value), but every time you use a custom Hook, all state and effects inside of it are fully isolated.
148
+
**在两个组件中使用相同的 Hook 会共享 state 吗?**不会。自定义 Hooks 是一种重用*状态逻辑*的机制(例如设置为订阅并存储当前值),所以每次使用自定义 Hook 时,其中的所有 state 和副作用都是完全隔离的。
149
149
150
-
**How does a custom Hook get isolated state?** Each *call* to a Hook gets isolated state. Because we call `useFriendStatus` directly, from React's point of view our component just calls `useState`and`useEffect`. And as we [learned](/docs/hooks-state.html#tip-using-multiple-state-variables)[earlier](/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns), we can call `useState`and`useEffect` many times in one component, and they will be completely independent.
Since Hooks are functions, we can pass information between them.
154
+
由于 Hooks 本身就是函数,因此我们可以在它们之间传递信息。
155
155
156
-
To illustrate this, we'll use another component from our hypothetical chat example. This is a chat message recipient picker that displays whether the currently selected friend is online:
@@ -184,24 +184,24 @@ function ChatRecipientPicker() {
184
184
}
185
185
```
186
186
187
-
We keep the currently chosen friend ID in the `recipientID`state variable, and update it if the user chooses a different friend in the `<select>`picker.
187
+
我们将当前选择的好友 ID 保存在 `recipientID`状态变量中,并在用户从 `<select>`中选择其他好友时更新这个 state。
188
188
189
-
Because the `useState`Hook call gives us the latest value of the `recipientID`state variable, we can pass it to our custom `useFriendStatus` Hook as an argument:
This lets us know whether the *currently selected* friend is online. If we pick a different friend and update the `recipientID`state variable, our `useFriendStatus` Hook will unsubscribe from the previously selected friend, and subscribe to the status of the newly selected one.
Custom Hooks offer the flexibility of sharing logic that wasn't possible in React components before. You can write custom Hooks that cover a wide range of use cases like form handling, animation, declarative subscriptions, timers, and probably many more we haven't considered. What's more, you can build Hooks that are just as easy to use as React's built-in features.
Try to resist adding abstraction too early. Now that function components can do more, it's likely that the average function component in your codebase will become longer. This is normal -- don't feel like you *have to* immediately split it into Hooks. But we also encourage you to start spotting cases where a custom Hook could hide complex logic behind a simple interface, or help untangle a messy component.
For example, maybe you have a complex component that contains a lot of local state that is managed in an ad-hoc way. `useState`doesn't make centralizing the update logic any easier so might you prefer to write it as a [Redux](https://redux.js.org/) reducer:
@@ -218,9 +218,9 @@ function todosReducer(state, action) {
218
218
}
219
219
```
220
220
221
-
Reducers are very convenient to test in isolation, and scale to express complex update logic. You can further break them apart into smaller reducers if necessary. However, you might also enjoy the benefits of using React local state, or might not want to install another library.
221
+
Reducers 非常便于单独测试,且易于扩展,以表达复杂的更新逻辑。如有必要,您可以将它们分成更小的 reducer。但是,你可能还享受着 React 内部 state 带来的好处,或者可能根本不想安装其他库。
222
222
223
-
So what if we could write a `useReducer` Hook that lets us manage the *local*state of our component with a reducer? A simplified version of it might look like this:
223
+
那么,为什么我们不编写一个 `useReducer`的 Hook,使用 reducer 的方式来管理组件的内部 state 呢?其简化版本可能如下所示:
224
224
225
225
```js
226
226
functionuseReducer(reducer, initialState) {
@@ -235,7 +235,7 @@ function useReducer(reducer, initialState) {
235
235
}
236
236
```
237
237
238
-
Now we could use it in our component, and let the reducer drive its state management:
238
+
在组件中使用它,让 reducer 驱动它管理 state:
239
239
240
240
```js{2}
241
241
function Todos() {
@@ -249,4 +249,4 @@ function Todos() {
249
249
}
250
250
```
251
251
252
-
The need to manage local state with a reducer in a complex component is common enough that we've built the `useReducer` Hook right into React. You'll find it together with other built-in Hooks in the [Hooks API reference](/docs/hooks-reference.html).
252
+
在复杂组件中使用 reducer 管理内部 state 的需求很常见,我们已经将 `useReducer`的 Hook 内置到 React 中。你可以在 [Hooks API 参考](/docs/hooks-reference.html)中找到它使用,搭配其他内置的 Hook 一起使用。
0 commit comments