React:如何在函数内调用含Hook的登出功能?令牌过期处理问题
问题:React中调用含Hook的Logout函数触发Hook使用错误
你的问题出在把Logout写成了React组件(因为它内部使用了useAuth Hook),却试图像普通函数一样直接调用它。React的Hook规则明确要求:Hook只能在组件的顶层作用域或者自定义Hook中调用,不能在异步回调、普通函数内部间接调用组件(这会导致Hook在非允许的时机执行)。
解决方案:抽离登出逻辑为工具函数,复用逻辑而非调用组件
1. 把登出核心逻辑抽成独立工具函数
创建一个单独的工具文件(比如authUtils.js),把登出的API请求、状态清除逻辑抽出来,不再依赖组件内的Hook,而是把需要的setAuth作为参数传入:
import axios from 'axios'; // 执行后端登出请求 const performLogoutRequest = () => { const axiosInstance = axios.create({ withCredentials: true }); return axiosInstance.get("http://localhost:8080/api/auth/logout") .then(response => { console.log(response); }) .catch(error => { console.log(error.config); }); }; // 通用登出处理函数 export const handleLogout = async (setAuth) => { // 清空AuthContext中的令牌 setAuth({ token: '' }); // 清除本地存储 localStorage.removeItem("access_token"); localStorage.clear(); // 调用后端登出接口 await performLogoutRequest(); // 跳转到登录页 window.location.href = '/auth'; };
2. 在股票数据请求的组件中调用工具函数
在你的股票数据组件中,先通过useAuth获取setAuth,然后在错误捕获时调用handleLogout,同时记得判断错误状态是否为403:
import { useAuth } from './path-to-AuthContext'; import { handleLogout } from './path-to-authUtils'; // ... 组件其他逻辑 const { setAuth } = useAuth(); useEffect(() => { (async () => { const response = await getStockData(); // ... 原有处理股票数据的逻辑 })().catch(async (error) => { // 仅当返回403时执行登出 if (error.response?.status === 403) { await handleLogout(setAuth); } }); }, [setAuth]); // 将setAuth加入依赖数组,确保最新的状态更新函数被使用
3. 重构原Logout组件(如果是用于按钮点击)
如果你原来的Logout是作为点击触发的组件,直接复用同一个工具函数即可:
import { useAuth } from './path-to-AuthContext'; import { handleLogout } from './path-to-authUtils'; const LogoutButton = () => { const { setAuth } = useAuth(); const onLogoutClick = async () => { await handleLogout(setAuth); }; return <button onClick={onLogoutClick}>退出登录</button>; }; export default LogoutButton;
这样既遵守了React的Hook规则,又实现了登出逻辑的复用,不会再触发Hook使用错误。
内容的提问来源于stack exchange,提问作者Omegon
相关产品推荐
相关产品推荐

