kangyana / daily-question

When your heart is set on something, you get closer to your goal with each passing day.
https://www.webpack.top
MIT License
3 stars 0 forks source link

【Q074】如何自己封装一个 Hooks #74

Open kangyana opened 2 years ago

kangyana commented 2 years ago

1. 自定义 Hook

通过自定义 Hook,可以将组件逻辑提取到可重用的函数中。

自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 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;
}

与 React 组件不同的是,自定义 Hook 不需要具有特殊的标识。 我们可以自由的决定它的参数是什么,以及它应该返回什么。 换句话说,它就是一个正常的函数。 但是它的名字应该始终以 use 开头,这样可以一眼看出其符合 Hook 的规则

2. 使用自定义 Hook

function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);

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

自定义 Hook 必须以 “use” 开头吗?

必须如此,这个约定非常重要。 不遵循的话,由于无法判断某个函数是否包含对其内部 Hook 的调用, React 将无法自动检查你的 Hook 是否违反了 Hook 的规则

在两个组件中使用相同的 Hook 会共享 state 吗?

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

自定义 Hook 如何获取独立的 state?

每次调用 Hook,它都会获取独立的 state