钩子如何知道何时触发(或不触发)useEffect 的主体?

时间:2021-01-31 11:59:39

标签: reactjs react-hooks

看官方的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 中的“连接”逻辑。

我认为如果 useEffectfriendID 作为第二个参数,这会起作用,但是作为新手我不想假设官方文档不是以弹性方式编写的,这意味着我错了,反应管道不知何故知道不连接每个重新渲染 - 但如何?

1 个答案:

答案 0 :(得分:1)

对于 useEffect,您需要提供一个将要执行的回调,以及一个决定何时触发效果的值数组(可选)。这里有三个选项:

  1. 你什么都不传递 - 每次渲染组件时都会触发 useEffect

  2. 您传递一个空数组 - useEffect 仅在安装组件时触发一次

  3. 你传递一个包含 props 和 state 变量的数组 - useEffect 在组件第一次安装时被触发每次至少有一个变量发生变化

React 没有做任何其他事情来减少调用 useEffect 的次数,所以是的,您确实需要明确提供您的效果所依赖的变量(在您的情况下为 friendID

相关问题