为何PrivateRoutes组件在axios请求后始终无法返回true并渲染Outlet?
问题原因与解决方法
你的代码存在两个核心问题,导致认证成功后依然跳转至首页:
- 异步请求导致的初始跳转:组件初始化时
auth默认是false,此时会直接返回<Navigate to="/"/>触发路由跳转。虽然之后axios请求成功会把auth设为true,但此时PrivateRoutes组件已经因为页面跳转被卸载,后续状态更新不会生效。 - 重复发起请求:axios请求直接写在组件函数体内,每次组件渲染都会重新发起认证请求,造成不必要的资源浪费。
修改后的代码
import { Outlet, Navigate } from 'react-router-dom'; import { useState, useEffect } from 'react'; import axios from 'axios'; const PrivateRoutes = () => { const [auth, setAuth] = useState(false); const [loading, setLoading] = useState(true); const token = localStorage.getItem('token'); useEffect(() => { const checkAuth = async () => { try { await axios.get('http://localhost:3333/user/auth', { headers: { authorization: "Bearer " + token } }); setAuth(true); } catch (err) { setAuth(false); } finally { setLoading(false); } }; checkAuth(); }, [token]); // 加载状态下不跳转,等待认证结果 if (loading) { return <div>加载中...</div>; // 可替换为自定义加载组件或null } return auth ? <Outlet /> : <Navigate to="/" />; }; export default PrivateRoutes;
关键改动说明
- 用
useEffect包裹认证请求:确保请求只在组件挂载或token变化时执行一次,避免重复请求。 - 新增
loading状态:在认证请求未完成时,返回加载提示而非立即跳转,给异步请求留足处理时间。 - 重构为
async/await写法:让异步逻辑更清晰易读,同时用finally块确保无论请求成功或失败,都会结束加载状态。
内容的提问来源于stack exchange,提问作者metrallador10
相关产品推荐
相关产品推荐

