自定义 Hook

解决什么问题

在 React 中,主要通过 render props高阶组件 这两种方式来共享组件之间的状态逻辑。

自定义Hook 可以在不增加组件的情况下,解决共享组件间状态逻辑的问题。

使用

自定义Hook 是一个函数,其内部可以调用(只能在顶层调用)其他的 Hook。我们可以自由的决定它的参数是什么,以及它应该返回什么(如果需要的话)。

自定义 Hook 必须以 “use” 开头吗?必须如此。React用名称来识别Hook,进而去判断Hook使用是否规范。

在两个组件中使用相同的 Hook 会共享 state 吗?不会。自定义Hook 是一种重用状态逻辑的机制(例如设置为订阅并存储当前值),所以每次使用自定义Hook 时,其中的所有 state 和副作用都是完全隔离的。

自定义 Hook 如何获取独立的 state?每次调用 Hook,它都会获取独立的 state。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//定义自定义hook
import React, { useState, useEffect } from 'react';

function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);

useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}

ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
};
});

return isOnline;
}

//使用自定义hook
function FriendStatus(props) {
const isOnline = useFriendStatus(props.friend.id);

if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}

//使用自定义hook
function FriendListItem(props) {
const isOnline = useFriendStatus(props.friend.id);

return (
<li style={{ color: isOnline ? 'green' : 'black' }}>
{props.friend.name}
</li>
);
}

注意

可以在多个 Hook 之间传递消息。