React Router Dom 私有路由无法正常跳转问题求助
私有路由认证后仍跳转到登录页的问题排查与修复
问题核心
控制台能打印reaching private route!,说明后端已返回认证成功,但页面仍跳转到登录页——本质是认证请求的异步逻辑未被正确等待,导致isLoading提前置为false,此时isAuthenticated仍为初始的undefined,触发了跳转逻辑。
代码问题分析
checkAuth声明为async函数,但内部使用Axios.post().then().catch()的回调写法,未用await等待请求完成。这会导致try块同步代码执行完后直接进入finally,把isLoading设为false,而此时Axios请求仍处于pending状态,isAuthenticated还是初始的undefined。组件渲染时,isAuthenticated ? children : <Navigate/>中undefined会被隐式判定为false,因此触发跳转。
修复方案
将Axios的回调写法改为await,确保认证请求完成后再更新状态并结束loading:
import { useState, useEffect } from 'react'; import { Navigate } from 'react-router-dom'; import Axios from "axios"; import Cookies from "universal-cookie"; export default function ProtectedRoute({ children }) { const [isAuthenticated, setIsAuthenticated] = useState(); const [isLoading, setIsLoading] = useState(true); const checkAuth = async () => { const cookie = new Cookies(); try { const sessionToken = cookie.get("stytch_session"); if (!sessionToken) { console.log("no cookies!") setIsAuthenticated(false); } else { await Axios.post( "http://localhost:5001/test", {}, { headers: { sessiontoken: sessionToken } } ); console.log("reaching private route!") setIsAuthenticated(true); } } catch (err) { console.log(err) setIsAuthenticated(false); } finally { setIsLoading(false); } }; useEffect(() => { checkAuth(); }, []); if (isLoading) { return <div className="">Loading...</div>; } // 明确判断认证状态,避免undefined被误判 return isAuthenticated === true ? children : <Navigate to={"/login"} />; }
额外优化点
- 解构出
sessionToken,避免重复调用cookie.get - return时明确判断
isAuthenticated === true,依赖显式判断而非隐式类型转换,防止意外跳转 - 移除未使用的
useRef、Outlet、useLocation导入,精简代码
内容的提问来源于stack exchange,提问作者kruskal123
相关产品推荐
相关产品推荐

