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
+35-35
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: 打造你自己的 Hook
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
+
*Hook* 是 React 16.8 中增加的新功能。它讓你不必寫 class 就能使用 state 以及其他 React 的功能。
10
10
11
-
Building your own Hooks lets you extract component logic into reusable functions.
11
+
打造你自己的 Hook 可以將 component 邏輯提取到可重複使用的 function 中。
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!
72
+
當我們想要共享邏輯在兩個 JavaScript function 之間時,我們提取它成為第三個 function。Component 和 Hook 兩者都是 function,所以這也適用於它們!
73
73
74
-
**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.
Now that we've extracted this logic to a `useFriendStatus` hook, we can *just use it:*
119
+
現在,我們提取了邏輯到 `useFriendStatus` hook,我們可以*使用它:*
120
120
121
121
```js{2}
122
122
function FriendStatus(props) {
@@ -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.**
144
+
**這個程式碼相等於原始的範例嗎?**是的,它們執行的方式是相同的。如果你仔細看的話,你會注意到我們沒有改變任何的行為。我們所做的只是在兩個 function 中提取共同的程式碼讓它成為一個獨立的 function。**自定義的 Hook 是自然遵循 Hook 設計的規範,而不是 React 的功能。**
145
145
146
-
**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.
146
+
**請問我必須以「`use`」開頭命名我自定義的 Hook 嗎?**請這麼做。這個規範非常的重要。沒有它的話,我們無法自動的檢查違反 [Hook 規則](/docs/hooks-rules.html)的行為,因為我們無法判斷某個 function 中是否包含對 Hook 的呼叫。
147
147
148
-
**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
+
**請問兩個 component 使用相同的 Hook 是共享 state 的嗎?**不是的。自定義的 Hook 有一個機制重複使用 *stateful 邏輯*(例如設定訂閱並記住目前的值),但每次你使用自定義的 Hook 時,所有內部的 state 和 effect 都是完全獨立的
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
+
由於 Hook 是 function,我們可以在它們之間傳遞資訊。
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` state 變數中,如果使用者在 `<select>`選擇器中選擇不同的使用者它將會更新。
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:
189
+
因為呼叫了 `useState` Hook 為我們提供了 `recipientID` state 變數的最新值,我們可以將它作為變數傳遞到我們自定義的 `useFriendStatus`:
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.
196
+
這讓我們知道*目前選擇的*朋友是否在線上。如果我們選擇不同的朋友並更新 `recipientID` state 變數,我們的 `useFriendStatus` Hook 將會從先前選擇的朋友中取消訂閱,並訂閱最新選擇的狀態。
197
197
198
198
## `useYourImagination()` {#useyourimagination}
199
199
200
-
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.
202
+
盡量不要過早地加入抽象。現在 function component 可以做更多的事,在你 codebase 中的 function component 程式碼平均可能都會變得更長。這都是正常的 -- 不要覺得你*必須*馬上把它拆分成 Hook。但我們也鼓勵你開始發現自定義的 Hook 可以隱藏簡單 interface 背後的複雜邏輯情況,或者幫忙解開一個混亂的 component。
203
203
204
-
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 you might prefer to write it as a [Redux](https://redux.js.org/) reducer:
204
+
例如,你可能有一個複雜的 component,它包含許多以 ad-hoc 的方式來管理 local state。`useState`沒辦法讓更新邏輯集中化,所以你可能更傾向將其寫為 [Redux](https://redux.js.org/)的 reducer:
205
205
206
206
```js
207
207
functiontodosReducer(state, action) {
@@ -211,16 +211,16 @@ function todosReducer(state, action) {
211
211
text:action.text,
212
212
completed:false
213
213
}];
214
-
// ... other actions ...
214
+
// ... 其他 action ...
215
215
default:
216
216
return state;
217
217
}
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
+
Redcer 是非常方便於獨立測試的,而且可以表達複雜的更新邏輯。如果有需要的話,你可以將它們拆成更小的 reducer。然而,你可能也喜歡使用 React local 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:
@@ -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
+
現在我們在其他的 component 使用它,讓 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
+
在複雜的 componnet 中使用 reducer 管理 local state 的需求很常見,我們已經將 `useReducer` Hook 內建在 React 中。你可以在 [Hooks API 參考](/docs/hooks-reference.html)中找到它與其他內建的 Hook。
0 commit comments