1
1
---
2
2
id : hooks-custom
3
- title : 自定义 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
9
* Hook* 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
10
10
11
- 通过自定义 Hooks ,可以将组件逻辑提取到可重用的函数中。
11
+ 通过自定义 Hook ,可以将组件逻辑提取到可重用的函数中。
12
12
13
13
在我们学习[ 使用 Effect Hook] ( /docs/hooks-effect.html#example-using-hooks-1 ) 时,我们已经见过这个聊天程序中的组件,该组件用于显示好友的在线状态:
14
14
@@ -65,13 +65,13 @@ function FriendListItem(props) {
65
65
66
66
相反,我们希望在 ` FriendStatus ` 和 ` FriendListItem ` 之间共享逻辑。
67
67
68
- 目前为止,在 React 中有两种流行的方式来共享组件之间的状态逻辑: [ render props] ( /docs/render-props.html ) 和[ 高阶组件] ( /docs/higher-order-components.html ) ,现在让我们来看看 Hooks 是如何在让你不增加组件的情况下解决相同问题的。
68
+ 目前为止,在 React 中有两种流行的方式来共享组件之间的状态逻辑: [ render props] ( /docs/render-props.html ) 和[ 高阶组件] ( /docs/higher-order-components.html ) ,现在让我们来看看 Hook 是如何在让你不增加组件的情况下解决相同问题的。
69
69
70
70
## 提取自定义 Hook {#extracting-a-custom-hook}
71
71
72
- 当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中。而组件和 Hooks 都是函数,所以也同样适用这种方式。
72
+ 当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中。而组件和 Hook 都是函数,所以也同样适用这种方式。
73
73
74
- ** 自定义 Hook 是一个函数,其名称以 “` use ` ” 开头,函数内部可以调用其他的 Hooks 。** 例如,下面的 ` useFriendStatus ` 是我们第一个自定义的 Hook:
74
+ ** 自定义 Hook 是一个函数,其名称以 “` use ` ” 开头,函数内部可以调用其他的 Hook 。** 例如,下面的 ` useFriendStatus ` 是我们第一个自定义的 Hook:
75
75
76
76
``` js{3}
77
77
import React, { useState, useEffect } from 'react';
@@ -94,7 +94,7 @@ function useFriendStatus(friendID) {
94
94
}
95
95
```
96
96
97
- 此处并未包含任何新的内容——逻辑是从上述组件拷贝来的。与组件中一致,请确保只在自定义 Hook 的顶层无条件地调用其他 Hooks 。
97
+ 此处并未包含任何新的内容——逻辑是从上述组件拷贝来的。与组件中一致,请确保只在自定义 Hook 的顶层无条件地调用其他 Hook 。
98
98
99
99
与 React 组件不同的是,自定义 Hook 不需要具有特殊的标识。我们可以自由的决定它的参数是什么,以及它应该返回什么(如果需要的话)。换句话说,它就像一个正常的函数。但是它的名字应该始终以 ` use ` 开头,这样可以一眼看出其符合 [ Hook 的规则] ( /docs/hooks-rules.html ) 。
100
100
@@ -141,17 +141,17 @@ function FriendListItem(props) {
141
141
}
142
142
```
143
143
144
- ** 这段代码等价于原来的示例代码吗?** 等价,它的工作方式完全一样。如果你仔细观察,你会发现我们没有对其行为做任何的改变,我们只是将两个函数之间一些共同的代码提取到单独的函数中。** 自定义 Hook 是一种自然遵循 Hooks 设计的约定,而并不是 React 的特性。**
144
+ ** 这段代码等价于原来的示例代码吗?** 等价,它的工作方式完全一样。如果你仔细观察,你会发现我们没有对其行为做任何的改变,我们只是将两个函数之间一些共同的代码提取到单独的函数中。** 自定义 Hook 是一种自然遵循 Hook 设计的约定,而并不是 React 的特性。**
145
145
146
- ** 自定义 Hooks 必须以 “` use ` ” 开头吗?** 必须如此。这个约定非常重要。不遵循的话,由于无法判断某个函数是否包含对其内部 Hooks 的调用,React 将无法自动检查你的 Hook 是否违反了 [ Hook 的规则] ( /docs/hooks-rules.html ) 。
146
+ ** 自定义 Hook 必须以 “` use ` ” 开头吗?** 必须如此。这个约定非常重要。不遵循的话,由于无法判断某个函数是否包含对其内部 Hook 的调用,React 将无法自动检查你的 Hook 是否违反了 [ Hook 的规则] ( /docs/hooks-rules.html ) 。
147
147
148
- ** 在两个组件中使用相同的 Hook 会共享 state 吗?** 不会。自定义 Hooks 是一种重用* 状态逻辑* 的机制(例如设置为订阅并存储当前值),所以每次使用自定义 Hook 时,其中的所有 state 和副作用都是完全隔离的。
148
+ ** 在两个组件中使用相同的 Hook 会共享 state 吗?** 不会。自定义 Hook 是一种重用* 状态逻辑* 的机制(例如设置为订阅并存储当前值),所以每次使用自定义 Hook 时,其中的所有 state 和副作用都是完全隔离的。
149
149
150
150
** 自定义 Hook 如何获取独立的 state?** 每次* 调用* Hook,它都会获取独立的 state。由于我们直接调用了 ` useFriendStatus ` ,从 React 的角度来看,我们的组件只是调用了 ` useState ` 和 ` useEffect ` 。 正如我们在[ 之前章节] ( /docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns ) 中[ 了解到的] ( /docs/hooks-state.html#tip-using-multiple-state-variables ) 一样,我们可以在一个组件中多次调用 ` useState ` 和 ` useEffect ` ,它们是完全独立的。
151
151
152
152
### 提示:在多个 Hook 之间传递信息 {#tip-pass-information-between-hooks}
153
153
154
- 由于 Hooks 本身就是函数,因此我们可以在它们之间传递信息。
154
+ 由于 Hook 本身就是函数,因此我们可以在它们之间传递信息。
155
155
156
156
我们将使用聊天程序中的另一个组件来说明这一点。这是一个聊天消息接收者的选择器,它会显示当前选定的好友是否在线:
157
157
@@ -197,9 +197,9 @@ function ChatRecipientPicker() {
197
197
198
198
## ` useYourImagination() ` {#useyourimagination}
199
199
200
- 自定义 Hooks 解决了以前在 React 组件中无法灵活共享逻辑的问题。你可以创建涵盖各种场景的自定义 Hooks ,如表单处理、动画、订阅声明、计时器,甚至可能还有其他我们没想到的场景。更重要的是,创建自定义 Hooks 就像使用 React 内置的功能一样简单。
200
+ 自定义 Hook 解决了以前在 React 组件中无法灵活共享逻辑的问题。你可以创建涵盖各种场景的自定义 Hook ,如表单处理、动画、订阅声明、计时器,甚至可能还有其他我们没想到的场景。更重要的是,创建自定义 Hook 就像使用 React 内置的功能一样简单。
201
201
202
- 尽量避免过早地增加抽象逻辑。既然函数组件能够做的更多,那么代码库中函数组件的代码行数可能会剧增。这属于正常现象 —— 不必立即将它们拆分为 Hooks 。但我们仍鼓励你能通过自定义 Hooks 寻找可能,以达到简化代码逻辑,解决组件杂乱无章的目的。
202
+ 尽量避免过早地增加抽象逻辑。既然函数组件能够做的更多,那么代码库中函数组件的代码行数可能会剧增。这属于正常现象 —— 不必立即将它们拆分为 Hook 。但我们仍鼓励你能通过自定义 Hook 寻找可能,以达到简化代码逻辑,解决组件杂乱无章的目的。
203
203
204
204
例如,有个复杂的组件,其中包含了大量以特殊的方式来管理的内部状态。` useState ` 并不会使得集中更新逻辑变得容易,因此你可能更愿意使用 [ redux] ( http://redux.js.org/ ) 中的 reducer 来编写。
205
205
@@ -249,4 +249,4 @@ function Todos() {
249
249
}
250
250
```
251
251
252
- 在复杂组件中使用 reducer 管理内部 state 的需求很常见,我们已经将 ` useReducer ` 的 Hook 内置到 React 中。你可以在 [ Hooks API 参考] ( /docs/hooks-reference.html ) 中找到它使用,搭配其他内置的 Hook 一起使用。
252
+ 在复杂组件中使用 reducer 管理内部 state 的需求很常见,我们已经将 ` useReducer ` 的 Hook 内置到 React 中。你可以在 [ Hook API 参考] ( /docs/hooks-reference.html ) 中找到它使用,搭配其他内置的 Hook 一起使用。
0 commit comments