React中LocalStorage无指定键值对时登出跳转报错问题
解决React登出功能中的Hook调用报错问题
问题描述
实现登出逻辑时,要求当localStorage中不存在"Admin Credentials"键值对、值为空或token过期时自动跳转到首页,但登录后手动删除该键值对时触发了Hook调用违规的报错。
报错原因
原代码中的VerifyAccessToken是普通函数,内部直接调用了useNavigate这个React Hook。根据React的Hook规则:Hook只能在React组件函数的顶层,或是自定义Hook的顶层调用,不能在普通函数、条件分支、循环中使用,否则会触发Hook调用违规的错误。
解决方案
1. 将验证函数改造为自定义Hook
修改TokenExpired.js,把普通函数改为以use开头的自定义Hook(React约定自定义Hook必须以use命名),这样就能合法调用其他Hook:
import { isExpired } from "react-jwt"; import { useNavigate } from "react-router-dom"; export const useVerifyAccessToken = () => { const navigate = useNavigate(); const storedData = localStorage.getItem('Admin Credentials'); // 合并条件判断,检查存储的数据是否有效 const isValidData = storedData !== null && storedData !== 'undefined' && storedData.trim() !== ''; if (isValidData) { try { const parsedData = JSON.parse(storedData); const isTokenExpired = isExpired(parsedData.accessToken); if (isTokenExpired) { localStorage.removeItem("Admin Credentials"); navigate('/'); } } catch (error) { // 处理JSON解析失败的情况(比如存储的数据格式损坏) localStorage.removeItem("Admin Credentials"); navigate('/'); } } else { localStorage.removeItem("Admin Credentials"); navigate('/'); } }
2. 在Dashboard组件中调用自定义Hook
在组件的顶层直接调用这个自定义Hook(符合Hook的调用规则):
import "./Dashboard.scss"; import { adminAuth } from "../../helpers/AdminInformation"; import { useVerifyAccessToken } from "../../helpers/TokenExpired"; // 组件导入 // certain components import { useEffect, useState } from "react"; const Dashboard = () => { const [dashboard, setDashboard] = useState({ received: 0, expected: 0 }) const token = adminAuth.accessToken; // 在组件顶层调用自定义Hook useVerifyAccessToken(); useEffect(() => { fetch(baseURL + 'api/dashboard/', { headers: { token: `Bearer ${token}` } }).then(res => res.json()).then(json => setDashboard(json)); }, [token]) return ( <div className="dashboard"> {/* 页面内容 */} </div> ); } export default Dashboard;
额外优化说明
- 新增JSON解析的错误捕获,避免因localStorage数据格式错误导致页面崩溃
- 合并重复的条件判断逻辑,简化代码结构
- 优化变量命名,提升代码可读性
内容的提问来源于stack exchange,提问作者Nahez Sakharkar
相关产品推荐
相关产品推荐

