自定义钩子是一个函数,如何触发另一个函数组件的重新渲染?

时间:2021-03-03 20:41:08

标签: javascript reactjs react-hooks

official docs of 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,所以我认为它只是返回{{1 }}:

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; } 是一个 AJAX 调用,所以当代码最终执行 ChatAPI.subscribeToFriendStatus() 时,比如说,0.7 秒后,这实际上如何触发 setIsOnline(true) 重新呈现?

>

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

换句话说,函数 A 如何从函数 B 取回 setData(),而函数 B 中设置的某些东西可以神奇地触发函数 A 运行?

2 个答案:

答案 0 :(得分:2)

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

考虑这两种情况:

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 眼中是“扁平化的”,它只关心正在渲染的组件和原生钩子的执行顺序。

答案 1 :(得分:1)

简而言之,自定义钩子没有做任何特别的事情,它只是一个函数。之所以这样称呼它们,是因为它们使用“原始”钩子,因此必须按照钩子规则使用。

当 React 执行一个组件时,它会跟踪它引用的是哪个实例,并且所有钩子都附加到该组件上。

这意味着实际上,useState 是在调用 useFriendStatus 的组件范围内执行的,因此 React 知道当状态被 {{1 }}。