React v6嵌套路由无法渲染Dashboard组件的问题排查
问题描述
我正在使用React构建一个简单的SPA,应用包含无需认证的公开页面(如首页/关于/定价等),以及用户点击登录按钮后通过Keycloak认证进入的应用组件。
我通过父路由管理公开页面的跳转,在SecuredPage内嵌套子路由管理应用内页面,但遇到问题:应用路由逻辑正常,但认证后无法渲染Dashboard组件。
相关代码
App.js
import React from "react"; import { BrowserRouter, Route, Routes } from "react-router-dom"; import HomePage from "./pages/Homepage"; import AboutPage from "./pages/AboutPage"; import SecuredPage from "./pages/Securedpage"; import PricingPage from "./pages/PricingPage"; function App() { return ( <div> <BrowserRouter> <Routes> <Route exact path="/" element={<HomePage />} /> <Route path="/about" element={ <AboutPage />} /> <Route path="/pricing" element={ <PricingPage />} /> <Route exact path="/app" element={ <SecuredPage />} /> </Routes> </BrowserRouter> </div> ); } export default App;
HomePage.js
import React from 'react'; import NavMain from "../components/NavMain"; const Home = () => { return ( <div> <NavMain/> <h1 className="text-green-800 text-4xl">Welcome to the Homepage. Some more text123</h1> </div> ); }; export default Home;
NavMain.js
<ul> <li> <a href="/">Home</a> </li> <li> <a href="/about">About</a> </li> <li> <a href="/pricing">pricing</a> </li> <li> <a href="/app/dashboard">app</a> </li> </ul>
SecuredPage.js
import React from 'react'; import { BrowserRouter, Route, Routes } from "react-router-dom"; import { ReactKeycloakProvider } from "@react-keycloak/web"; import keycloak from "../Keycloak"; import Dashboard from "./Dashboardpage"; import AboutPage from "./AboutPage"; import PrivateRoutes from "../helpers/PrivateRoutes"; import NavHomePage from "../components/NavHomePage"; const Loading = () => <div>Loading...</div> const Secured = () => { return ( <div> <ReactKeycloakProvider authClient={keycloak} initOptions={{ onLoad: "login-required", }} LoadingComponent={<Loading />} > app landing page <NavHomePage/> <Routes> <Route element={<PrivateRoutes />}> <Route exact path="/app/dashboard" element={ <Dashboard />} /> </Route> </Routes> </ReactKeycloakProvider> </div> ); }; export default Secured;
Dashboard.js
import React from 'react'; const Dashboard = () => { return ( <div> <h1 className="text-green-800 text-4xl">Dashboard</h1> </div> ); }; export default Dashboard;
NavHomePage.js
<Navbar bg="dark" variant="dark"> <Container> <Navbar.Brand href="/">Hype</Navbar.Brand> <Navbar.Toggle aria-controls="basic-navbar-nav" /> <Navbar.Collapse id="basic-navbar-nav"> <Nav className="me-auto"> <Nav.Link href="/app">Home</Nav.Link> <Nav.Link href="/app/dashboard">dashboard</Nav.Link> </Nav> <Nav className="ml-auto"> {!!keycloak.authenticated && ( <Nav.Link onClick={() => logoutHelper()}> Logout ({keycloak.tokenParsed.preferred_username})</Nav.Link>)} </Nav> </Navbar.Collapse> </Container> </Navbar>
PrivateRoutes.js
const PrivateRoutes = () => { const { keycloak } = useKeycloak(); const isLoggedIn = keycloak.authenticated; console.log("checking auth access " + isLoggedIn); console.log(keycloak); return isLoggedIn ? <Outlet/> : null; };
解决方案
1. 修正嵌套路由路径
SecuredPage对应父路由/app,子路由需使用相对路径而非绝对路径。修改SecuredPage.js中的路由配置:
// 原代码 <Route exact path="/app/dashboard" element={ <Dashboard />} /> // 修改后 <Route path="dashboard" element={<Dashboard />} />
2. 移除重复的BrowserRouter
根组件App.js已通过BrowserRouter包裹整个应用,SecuredPage.js中无需再次引入,避免路由上下文冲突:
// 删除该行导入 import { BrowserRouter, Route, Routes } from "react-router-dom";
3. 确保父路由支持子路由渲染
修改App.js中/app的路由定义,允许其渲染子路由:
// App.js 修改后 <Route path="/app" element={<SecuredPage />}> {/* 子路由在SecuredPage内部定义,此处无需添加 */} </Route>
4. 补全PrivateRoutes组件依赖
确保PrivateRoutes正确导入所需依赖:
// PrivateRoutes.js 完整代码 import { Outlet } from 'react-router-dom'; import { useKeycloak } from '@react-keycloak/web'; const PrivateRoutes = () => { const { keycloak } = useKeycloak(); const isLoggedIn = keycloak.authenticated; console.log("checking auth access " + isLoggedIn); return isLoggedIn ? <Outlet /> : null; }; export default PrivateRoutes;
完成以上修改后,认证后访问/app/dashboard即可正常渲染Dashboard组件。
内容的提问来源于stack exchange,提问作者ksernow
相关产品推荐
相关产品推荐

