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
相关产品推荐
相关产品推荐

