看官方的react docs,给出了一个写自定义hook的例子,如下:
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;
}
function ChatRecipientPicker() {
const [recipientID, setRecipientID] = useState(1);
const isRecipientOnline = useFriendStatus(recipientID);
return (
<>
<Circle color={isRecipientOnline ? 'green' : 'red'} />
<select
value={recipientID}
onChange={e => setRecipientID(Number(e.target.value))}
>
{friendList.map(friend => (
<option key={friend.id} value={friend.id}>
{friend.name}
</option>
))}
</select>
</>
);
}
我感到困惑的部分 - 我的理解是 useEffect(...)
将在每次组件重新渲染时触发,正如目前所描述的,只有在调用 setRecipientID
时才会发生。但是,假设添加了另一个状态变量,例如 const [nameFilter, setNameFilter] = useState('')
。在这种情况下,每次用户输入过滤器时,组件都会重新渲染,我认为这会触发 useEffect
中的“连接”逻辑。
我认为如果 useEffect
将 friendID
作为第二个参数,这会起作用,但是作为新手我不想假设官方文档不是以弹性方式编写的,这意味着我错了,反应管道不知何故知道不连接每个重新渲染 - 但如何?
答案 0 :(得分:1)
对于 useEffect
,您需要提供一个将要执行的回调,以及一个决定何时触发效果的值数组(可选)。这里有三个选项:
你什么都不传递 - 每次渲染组件时都会触发 useEffect
您传递一个空数组 - useEffect
仅在安装组件时触发一次
你传递一个包含 props 和 state 变量的数组 - useEffect
在组件第一次安装时被触发和每次至少有一个变量发生变化
React 没有做任何其他事情来减少调用 useEffect
的次数,所以是的,您确实需要明确提供您的效果所依赖的变量(在您的情况下为 friendID
)