React受保护路由出现不应有的重定向问题
问题修复:登录状态判断前提前触发重定向
你的问题核心是loading状态在异步请求完成前就被设置为false,导致loggedIn还保持初始的false值时,Protected组件就执行了重定向逻辑,哪怕后续请求成功更新了loggedIn,也已经来不及阻止重定向了。
修复步骤:
把setLoading(false)移到异步请求的finally回调中,确保只有在登录状态请求完成(成功或失败)后,才结束加载状态,让Protected组件根据最终的loggedIn值判断是否重定向。
修改后的代码:
App组件部分:
function App() { const [user, setUser] = useState(null); const [loggedIn, setLoggedIn] = useState(false); const [loading, setLoading] = useState(true); useEffect(() => { axios.get('/me') .then(res => { setUser(res.data) setLoggedIn(true); }) .catch(err => { setLoggedIn(false); }) // 无论请求成功或失败,都在请求完成后结束加载 .finally(() => { setLoading(false); }); }, []); const router = createBrowserRouter([ { path: '/', element: ( <Protected user={user} loggedIn={loggedIn} loading={loading}> <Home /> </Protected> ), }, // 其他路由配置... ]); return <RouterProvider router={router} />; }
Protected组件(无需修改):
const Protected = ({ user, loggedIn, loading, children }) => { if (loading) { return null; // 加载中时不渲染任何内容,避免提前判断 } if (!loggedIn) { return <Navigate to="/login" replace />; } return children; };
补充说明:
原代码中useEffect的return语句会在组件挂载后立刻触发(空依赖数组的useEffect,其清理函数会在组件卸载时执行),这就导致loading在axios请求还没响应时就变成了false,Protected组件此时读取到的loggedIn还是初始的false,直接触发重定向。用finally回调可以保证不管请求成功还是失败,都会在请求结束后更新loading状态,确保Protected组件判断的是最终的登录状态。
内容的提问来源于stack exchange,提问作者Noah Dennis
相关产品推荐
相关产品推荐

