ProtectedRoute页面刷新重定向问题:authState未更新时跳转至登录页
问题现象
- 通过
/login页面登录后,可正常跳转至/profile页面;但刷新/profile页面时会被重定向至/login页面 - 认证状态(authState)通过
redux-persist存储在localStorage中,checkAuth()用于验证Cookie中的JWT accessToken
问题原因与解决方案
- 原因:页面刷新时Redux状态会重置为初始状态,
redux-persist要等之后才会恢复(rehydrates)状态,这期间认证状态未恢复,导致ProtectedRoute判定用户未认证而触发重定向 - 解决方案:将未确认的认证状态设为
null,并在状态恢复期间保持loading为true,无需在ProtectedRoute中额外添加状态恢复检查,方案简洁高效
相关代码实现
src/components/ProtectedRoute.tsx
import { Navigate, useLocation } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { RootState } from '@/store/store'; import useAuthGuard from '@/hooks/useAuthGuard'; interface ProtectedRouteProps { children: React.ReactNode; } export const ProtectedRoute = ({ children }: ProtectedRouteProps): JSX.Element => { const { user, loading, isAuthenticated } = useSelector((state: RootState) => state.auth); const location = useLocation(); console.log('Full Auth State:', { user, loading, isAuthenticated, currentPath: location.pathname }); // 使用自定义钩子确保认证检查 useAuthGuard(); console.log(`console->log ${location.pathname}`, user); // 仍在加载时(比如验证token过程中),渲染加载占位 if (loading) { return <div>Loading...</div>; // 替换为你项目的加载组件 } // 检查用户未认证且当前不在登录页 if (!isAuthenticated || !user) { // 重定向到登录页并保留目标路径 console.log('Redirecting to login...'); return <Navigate to="/login" state={{ from: location.pathname }} replace />; } return <> {children} </>; };
src/hooks/useAuthGuard.ts
import { useSelector, useDispatch } from 'react-redux'; import { RootState, AppDispatch } from '@/store/store'; import { useEffect } from 'react'; export const useAuthGuard = () => { const { user, isAuthenticated, loading } = useSelector((state: RootState) => state.auth); const dispatch = useDispatch<AppDispatch>(); useEffect(() => { const verifyAuth = async () => { try { // 同时检查认证状态和用户数据 if (!loading && (!isAuthenticated || !user)) { await dispatch(checkAuth()).unwrap(); } } catch (error) { console.error('Auth check failed, redirecting to login'); } }; verifyAuth(); }, [isAuthenticated, loading, dispatch]); };
内容的提问来源于stack exchange,提问作者Shi O
相关产品推荐
相关产品推荐

