React Router v6 如何通过嵌套路由实现根路径动态渲染页面
React Router v6 实现根路径动态渲染及嵌套路由权限控制
核心思路
通过根布局组件判断认证状态,动态渲染对应内容;同时用两个路由守卫组件分别保护私有/公共路由,实现嵌套路由的权限控制,既满足根路径/的动态渲染需求,又符合嵌套路由的设计规范。
实现步骤
1. 调整私有路由守卫(AuthRouter)
修改原AuthRouter逻辑,未认证用户访问私有路由时跳转到根路径而非登录页:
import { useAuth } from '@src/hooks'; import { Navigate, Outlet } from 'react-router-dom'; import { routeConstants } from '@src/constants'; const AuthRouter = () => { const { user } = useAuth(); if (!user) { // 未认证访问私有路由时跳转到根路径(显示落地页) return <Navigate to={routeConstants.Routes.Index} replace />; } return <Outlet />; }; export default AuthRouter;
2. 创建公共路由守卫(PublicRouter)
用于防止已认证用户访问登录/注册页面:
import { useAuth } from '@src/hooks'; import { Navigate, Outlet } from 'react-router-dom'; import { routeConstants } from '@src/constants'; const PublicRouter = () => { const { user } = useAuth(); if (user) { // 已认证用户访问公共路由时跳转到根路径(显示Dashboard) return <Navigate to={routeConstants.Routes.Index} replace />; } return <Outlet />; }; export default PublicRouter;
3. 创建根布局组件(RootLayout)
作为根路径的容器,根据认证状态动态渲染Dashboard或落地页,并承载私有子路由的Outlet:
import { useAuth } from '@src/hooks'; import { Outlet } from 'react-router-dom'; import { Pages } from './pages'; const RootLayout = () => { const { user } = useAuth(); if (user) { // 已认证时渲染Dashboard,Outlet用于嵌套私有子路由(如settings、profile) return ( <Pages.Dashboard> <Outlet /> </Pages.Dashboard> ); } // 未认证时渲染落地页 return <Pages.LandingPage />; }; export default RootLayout;
4. 配置全局路由
将根布局、私有/公共路由守卫整合到路由配置中:
import { Routes, Route } from 'react-router-dom'; import AuthRouter from './AuthRouter'; import PublicRouter from './PublicRouter'; import RootLayout from './RootLayout'; import { Pages } from './pages'; import { routeConstants } from '@src/constants'; function App() { return ( <Routes> {/* 根路径:动态渲染Dashboard/落地页 */} <Route path={routeConstants.Routes.Index} element={<RootLayout />}> {/* 私有子路由:需AuthRouter保护 */} <Route element={<AuthRouter />}> <Route path={routeConstants.Routes.Settings} element={<Pages.Settings />} /> <Route path={routeConstants.Routes.Profile} element={<Pages.Profile />} /> </Route> </Route> {/* 公共路由:需PublicRouter保护 */} <Route element={<PublicRouter />}> <Route path={routeConstants.Routes.LogIn} element={<Pages.Login />} /> <Route path={routeConstants.Routes.SignUp} element={<Pages.Signup />} /> </Route> {/* 404页面 */} <Route path="*" element={<Pages.NotFound />} /> </Routes> ); } export default App;
效果说明
- 访问
/:已认证用户看到Dashboard,未认证用户看到落地页 - 访问
/settings//profile:未认证用户自动跳转到/显示落地页;已认证用户在Dashboard布局内看到对应子页面 - 访问
/login//signup:已认证用户自动跳转到/显示Dashboard;未认证用户看到对应登录/注册页面
内容的提问来源于stack exchange,提问作者Sags
相关产品推荐
相关产品推荐

