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

切换同父级嵌套子路由时,如何触发useVerifyToken钩子执行?

解决方案

核心问题分析

你遇到两个关键问题:

  1. useVerifyToken 中用普通变量 data 存储校验状态,无法触发组件重渲染,导致校验结果无法同步到页面。
  2. 依赖 window.location.href 无法监听到同层级子路由切换——父路由组件 InauthenticatedRoutes 不会因子路由变化重新渲染,且闭包问题可能导致钩子无法捕捉到 window.location.href 的变化。

最优解决方案:改用 useLocation 监听路由变化

直接修改 useVerifyToken 钩子,利用 React Router 提供的 useLocation 替代 window.location.href,同时用 useState 管理校验状态:

import { useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';

function useVerifyToken() {
  // 用 useState 管理认证状态,确保状态变化能触发组件重渲染
  const [isAuthenticated, setIsAuthenticated] = useState(0);
  // 获取路由信息,子路由切换时 location 对象会更新
  const location = useLocation();

  useEffect(() => {
    const jwt = localStorage.getItem('access');
    
    // 替换为你的令牌校验逻辑(示例为异步校验)
    const verifyToken = async () => {
      let isValid = 0;
      try {
        // 这里可以是调用后端接口校验,或前端解析JWT验证有效性
        isValid = await yourActualVerifyLogic(jwt);
      } catch (err) {
        isValid = 0;
      }
      setIsAuthenticated(isValid);
    };

    verifyToken();
  }, [location]); // 依赖 location,路由(含子路由)变化时自动触发校验

  return isAuthenticated;
}

解决逻辑

  • useLocation 会在任何路由变化(包括同层级子路由切换)时返回新的 location 对象,确保 useEffect 能被触发。
  • 用 useState 存储校验状态,校验完成后会自动更新组件,让 InauthenticatedRoutes 能拿到最新的认证状态。

替代方案:手动触发校验(不修改钩子依赖)

如果不想改动钩子核心逻辑,可以在父路由组件中监听路由变化,手动触发校验:

  1. 修改 InauthenticatedRoutes 组件:
import React, { useEffect, useState } from 'react'
import { Route, Outlet, Navigate, useLocation } from 'react-router-dom'
import { Login, SignUp } from '../pages'
import useVerifyToken from '../hooks/useVerifyToken'

const InauthenticatedRoutes = () => {
  const location = useLocation();
  // 用状态变量强制触发钩子的校验逻辑
  const [triggerVerify, setTriggerVerify] = useState(0);
  const isAuth = useVerifyToken(triggerVerify);

  // 路由变化时更新 triggerVerify,触发钩子校验
  useEffect(() => {
    setTriggerVerify(prev => prev + 1);
  }, [location]);

  return !isAuth ? <Outlet /> : <Navigate to="/"/>
}
  1. 修改 useVerifyToken 钩子,添加 triggerVerify 作为依赖:
import React, { useEffect, useState } from 'react'

function useVerifyToken(triggerVerify) {
  const [isAuthenticated, setIsAuthenticated] = useState(0);

  useEffect(() => {
    const jwt = localStorage.getItem('access');
    
    // 你的令牌校验逻辑
    const verifyToken = async () => {
      // ...校验过程
      setIsAuthenticated(校验结果 ? 1 : 0);
    };

    verifyToken();
  }, [triggerVerify]) // 依赖触发变量

  return isAuthenticated;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:15:31