首页 > 解决方案 > 自定义钩子是一个函数,如何触发另一个函数组件的重新渲染?

问题描述

Custom React Hooks 的官方文档中,使用自定义钩子的一个示例是:

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

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

但是,第一次isOnline设置时,值应该是null,因为自定义钩子的初始状态是null,所以我认为它只是返回null

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;
}

因为ChatAPI.subscribeToFriendStatus()是 AJAX 调用,所以当代码最终setIsOnline(true)在 0.7 秒之后执行时,这实际上是如何触发FriendListItem()重新渲染的?

如果状态在组件内部是有意义的,因此我们可以setData()并导致组件重新渲染。但是一个函数是如何导致另一个函数(组件)被重新渲染的呢?

换句话说,函数A如何null从函数B中取回a,而在函数B中设置的东西可以神奇地触发函数A运行?

标签: javascriptreactjsreact-hooks

解决方案


React 提供了一些“本机”钩子(例如useState,useEffect等)。所有自定义钩子只是在某些时候调用本机钩子(或另一个遵守此规则的自定义钩子)的函数。

考虑以下两种情况:

const A = () => {
   const [s1, setS1] = useState()
   const [s2, setS2] = useState()

   ...
}

const useMyHook = () => {
   const [s2, setS2] = useState()
   // ..maybe do something here
   return [s2, setS2]
}
const B = () => {
   const [s1, setS1] = useState()
   const [s2, setS2] = useMyHook()

   ...
}

如果您遵循呼叫顺序,您会看到在这两种情况下我们只有两个useState呼叫。

本质上,自定义钩子在 React 眼中是“扁平化”的,它只关心正在渲染哪个组件以及本机钩子的执行顺序。


推荐阅读