You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在loginPopup API调用成功后调用自定义Hook useUserInfo?

解决React Hook不能在异步回调内调用的问题

你遇到的错误是因为违反了React Hook的核心规则:所有Hook必须在组件的顶层作用域调用,不能嵌套在条件判断、循环、异步函数或回调函数内部。你在loginPopup的异步回调中调用useUserInfo,直接触发了这个规则校验。

下面提供两种可行的解决方案:

方案一:通过useQuery的控制参数延迟查询

将useUserInfo提到组件顶层,利用react-query的enabled参数或refetch方法,在登录成功后触发用户信息查询:

// 修改自定义Hook,添加enabled参数控制查询时机
export const useUserInfo = (enabled = true) => {
  const query = useQuery({
    queryKey: ["users-info"],
    queryFn: () => fetchUserInfo(),
    enabled: enabled, // 仅当enabled为true时执行查询
  });
  return query;
};

const Auth = () => {
  const { instance } = useMsal();
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  // 在组件顶层调用useUserInfo,符合Hook规则
  const { data: responseData, refetch } = useUserInfo(isLoggedIn);

  const handleLoginPopup = async () => {
    try {
      await instance.loginPopup(loginRequest);
      setIsLoggedIn(true); // 登录成功后开启查询
      
      // 若需要立即获取最新数据,可手动调用refetch
      // const freshData = await refetch();
      // console.log(freshData);
      
      navigate("/home");
    } catch (error) {
      console.error(error);
    }
  };

  // 监听用户信息数据变化,做后续处理
  useEffect(() => {
    if (responseData) {
      console.log(responseData);
    }
  }, [responseData]);

  // 组件其他渲染逻辑...
};

方案二:直接调用底层数据获取函数

如果不需要react-query提供的缓存、自动重试等特性,可直接在登录回调中调用fetchUserInfo原函数,绕过自定义Hook:

// 单独导出底层数据获取函数
export const fetchUserInfo = async () => {
  // 原fetchUserInfo的实现逻辑,比如接口请求
};

// 保留原自定义Hook供其他场景使用
export const useUserInfo = () => {
  const query = useQuery({
    queryKey: ["users-info"],
    queryFn: fetchUserInfo,
  });
  return query;
};

const Auth = () => {
  const { instance } = useMsal();

  const handleLoginPopup = async () => {
    try {
      await instance.loginPopup(loginRequest);
      // 直接调用fetchUserInfo异步函数,无需使用Hook
      const responseData = await fetchUserInfo();
      console.log(responseData);
      
      navigate("/home");
    } catch (error) {
      console.error(error);
    }
  };

  // 组件其他渲染逻辑...
};

核心思路

React Hook的规则是为了保证组件渲染时Hook的调用顺序稳定,避免状态错乱。所有Hook必须在组件的顶层(不能嵌套在任何逻辑块里)调用,若需要在事件触发后执行数据操作,要么通过Hook自身的控制参数(如useQuery的enabled),要么直接调用底层的异步函数。

内容的提问来源于stack exchange,提问作者ganesh kaspate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:55:26