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

React ProtectedRoute中useEffect渲染后执行致错误重定向问题求助

问题根源

你的ProtectedRoute组件初始将isLoggedIn设为false,而checkUserAccess()是异步操作——组件首次渲染时,异步校验还未完成,isLoggedIn仍为初始值false,因此会立刻触发重定向到登录页。等异步请求完成后isLoggedIn更新为true,但重定向已经执行,无法回退到目标页面。

解决方案

添加加载状态,在异步校验完成前不执行重定向或渲染受保护页面,避免提前触发跳转。修改后的ProtectedRoute.tsx代码如下:

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

import LoginService from '../../services/Login/login.service';

interface ProtectedRouteProps {
  children: React.ReactNode;
}

const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children }) => {
  const [isLoggedIn, setIsLoggedIn] = useState<boolean | null>(null); // 初始为null,表示未完成校验
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    async function checkAccess() {
      const loginService = new LoginService();
      try {
        const canAccess = await loginService.checkUserAccess();
        setIsLoggedIn(canAccess);
      } catch (err) {
        setIsLoggedIn(false); // 校验失败默认视为未登录
      } finally {
        setIsLoading(false); // 无论成功失败,结束加载状态
      }
    }

    checkAccess();
  }, []);

  // 加载中可显示自定义加载组件,或返回null保持空白
  if (isLoading) {
    return <div>加载中...</div>;
  }

  // 校验完成后再判断跳转或渲染页面
  return isLoggedIn ? children : <Navigate to='/login' replace />;
};

export default ProtectedRoute;
额外优化说明
  • 将isLoggedIn初始值设为null,清晰区分“未校验”和“未登录”两种状态
  • 给Navigate添加replace属性,避免浏览器回退栈保留受保护路由的跳转记录
  • 为异步请求添加try/catch,处理接口出错的情况,防止组件一直处于加载状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:05:12