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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:36:27