React Router v6.10 受保护路由无法渲染问题求助
React受保护路由无法渲染问题排查与解决
我正在构建一个包含受保护路由的React应用,PersistLogin组件负责向端点请求检查Cookie,若有效则将Token存入Redux store。目前受保护路由无报错但无法渲染,Token状态正常,以下是相关代码文件:
main.jsx
import React from "react"; import ReactDOM from "react-dom/client"; import { createBrowserRouter, RouterProvider } from "react-router-dom"; import "./index.css"; import store from "./app/store"; import { Provider } from "react-redux"; import Root from "./components/Root"; import PublicLayout from "./components/PublicLayout"; import PersistLogin from "./components/PersistLogin"; import RequireAuthLayout from "./components/RequireAuthLayout"; import { ErrorPage, Home, Login, Logout, Register } from "./pages"; const router = createBrowserRouter([ { path: "/*", element: <Root />, errorElement: <ErrorPage />, children: [ { element: <PublicLayout />, children: [ { path: "login", element: <Login /> }, { path: "register", element: <Register /> }, ], }, { element: <PersistLogin />, children: [ { element: <RequireAuthLayout />, children: [ { path: "home", element: <Home /> }, { path: "logout", element: <Logout /> }, ], }, ], }, ], }, ]); ReactDOM.createRoot(document.getElementById("root")).render( <React.StrictMode> <Provider store={store}> <RouterProvider router={router} /> </Provider> </React.StrictMode> );
Root.jsx
import React from "react"; import { Outlet } from "react-router-dom"; import Header from "./Header"; const Root = () => { return ( <> <Header /> <main> <Outlet /> </main> </> ); }; export default Root;
RequireAuthLayout.jsx
import React from "react"; import { useLocation, Navigate, Outlet } from "react-router-dom"; import { useSelector } from "react-redux"; import { selectCurrentToken } from ".././features/auth/authSlice"; const RequireAuthLayout = () => { const token = useSelector(selectCurrentToken); const location = useLocation(); return token ? ( <Outlet /> ) : ( <Navigate to="/login" state={{ from: location }} replace /> ); }; export default RequireAuthLayout;
PersistLogin.jsx
import React, { useEffect } from "react"; import { Outlet } from "react-router-dom"; import { useDispatch, useSelector } from "react-redux"; import { useRefreshMutation } from "../features/api/authApiSlice"; import { selectCurrentToken, setCredentials } from "../features/auth/authSlice"; import Loading from "../components/Loading"; const PersistLogin = () => { const [refresh, { isLoading, isError }] = useRefreshMutation(); const dispatch = useDispatch(); const token = useSelector(selectCurrentToken); let content; useEffect(() => { const getAccessToken = async () => { try { const result = await refresh(); dispatch(setCredentials(result.data)); } catch (error) { // console.log(error); } }; !token && getAccessToken(); }, []); if (isLoading) { content = <Loading />; } else if (isError) { content = <p>Bir hata oluştu, tekrar giriş yapınız!</p>; } else { <Outlet />; } return content; }; export default PersistLogin;
问题原因与修复方案
1. 核心问题:未将<Outlet />赋值给content变量
在PersistLogin组件的else分支中,仅写了<Outlet />但未将其赋值给content变量,导致组件在该分支下返回undefined,无法渲染子路由。
修复代码:
if (isLoading) { content = <Loading />; } else if (isError) { content = <p>Bir hata oluştu, tekrar giriş yapınız!</p>; } else { content = <Outlet />; // 补上赋值操作 }
2. 辅助修复:完善useEffect依赖数组
原useEffect的依赖数组为空,会导致闭包问题(比如token更新后无法正确触发逻辑),需要添加token、dispatch和refresh作为依赖:
修复代码:
useEffect(() => { const getAccessToken = async () => { try { const result = await refresh(); dispatch(setCredentials(result.data)); } catch (error) { // console.log(error); } }; !token && getAccessToken(); }, [token, dispatch, refresh]); // 添加缺失的依赖
完成以上修改后,受保护路由即可正常渲染。
内容的提问来源于stack exchange,提问作者ugurgunes
相关产品推荐
相关产品推荐

