如何在React Router特定路由下隐藏头部与导航栏?
问题
我已经用react-router配置了路由,让Header、导航栏(SBNavigation和SBTemplates)在所有页面显示,但登录页(/log-in)和注册页(/register)不需要展示这些组件。想问能不能在特定页面隐藏头部与导航栏,还是必须重构所有页面,把头部和导航栏逐个添加到需要的页面中?
现有路由代码
<div className="app"> <BrowserRouter> <Header /> <div className="app__structure"> <div className="app__structure-sidebar"> <SBNavigation /> <SBTemplates /> </div> <div className="app__structure-routes"> <Routes> <Route path="/log-in" element={<LoginPage />} /> <Route path="/register" element={<RegisterPage />} /> <Route path="/loading" element={<LoadingPage />} /> <Route path="/" element={<HomePage />} /> <Route path="/leads" element={<LeadsPage />} /> <Route path="/leads/:id" element={<EditExistingLead />} /> <Route path="/leads/add-new" element={<AddNewLead />} /> <Route path="/templates" element={<TemplatesPage />} /> <Route path="/templates/:id" /> <Route path="/editor" element={<EditorPage />} /> <Route path="/review/:id" element={<ReviewPage />} /> <Route path="/settings/:id" element={<SettingsPage />} /> <Route path="*" element={<NotFoundPage />} /> </Routes> </div> </div> </BrowserRouter> </div>
解决方案
不需要重构所有页面,有两种简单的方式实现特定页面隐藏Header和导航栏:
方法一:用useLocation判断当前路径
通过react-router提供的useLocation钩子获取当前路径,判断是否属于需要隐藏的页面,再决定是否渲染Header和导航栏。
修改后的代码:
import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom'; // 封装布局组件 const MainLayout = ({ children }) => { const location = useLocation(); // 定义无需展示Header和导航栏的路径 const excludedPaths = ['/log-in', '/register']; if (excludedPaths.includes(location.pathname)) { return <>{children}</>; } return ( <> <Header /> <div className="app__structure"> <div className="app__structure-sidebar"> <SBNavigation /> <SBTemplates /> </div> <div className="app__structure-routes">{children}</div> </div> </> ); }; function App() { return ( <div className="app"> <BrowserRouter> <MainLayout> <Routes> <Route path="/log-in" element={<LoginPage />} /> <Route path="/register" element={<RegisterPage />} /> <Route path="/loading" element={<LoadingPage />} /> <Route path="/" element={<HomePage />} /> <Route path="/leads" element={<LeadsPage />} /> <Route path="/leads/:id" element={<EditExistingLead />} /> <Route path="/leads/add-new" element={<AddNewLead />} /> <Route path="/templates" element={<TemplatesPage />} /> <Route path="/templates/:id" /> <Route path="/editor" element={<EditorPage />} /> <Route path="/review/:id" element={<ReviewPage />} /> <Route path="/settings/:id" element={<SettingsPage />} /> <Route path="*" element={<NotFoundPage />} /> </Routes> </MainLayout> </BrowserRouter> </div> ); }
方法二:使用嵌套路由拆分布局
把需要展示Header和导航栏的页面放到一个嵌套路由下,登录/注册页单独作为顶层路由,这种方式更符合react-router的结构设计。
修改后的代码:
import { BrowserRouter, Routes, Route, Outlet } from 'react-router-dom'; // 带Header和导航栏的布局组件 const AuthenticatedLayout = () => ( <> <Header /> <div className="app__structure"> <div className="app__structure-sidebar"> <SBNavigation /> <SBTemplates /> </div> <div className="app__structure-routes"> <Outlet /> {/* 渲染子路由内容 */} </div> </div> </> ); function App() { return ( <div className="app"> <BrowserRouter> <Routes> {/* 无需布局的页面直接放在顶层 */} <Route path="/log-in" element={<LoginPage />} /> <Route path="/register" element={<RegisterPage />} /> {/* 需要布局的页面嵌套在AuthenticatedLayout下 */} <Route element={<AuthenticatedLayout />}> <Route path="/loading" element={<LoadingPage />} /> <Route path="/" element={<HomePage />} /> <Route path="/leads" element={<LeadsPage />} /> <Route path="/leads/:id" element={<EditExistingLead />} /> <Route path="/leads/add-new" element={<AddNewLead />} /> <Route path="/templates" element={<TemplatesPage />} /> <Route path="/templates/:id" /> <Route path="/editor" element={<EditorPage />} /> <Route path="/review/:id" element={<ReviewPage />} /> <Route path="/settings/:id" element={<SettingsPage />} /> <Route path="*" element={<NotFoundPage />} /> </Route> </Routes> </BrowserRouter> </div> ); }
两种方法都无需修改现有页面,仅需调整路由结构或新增布局组件即可。其中方法二更符合react-router的最佳实践,路由结构更清晰,后续维护也更方便。
内容的提问来源于stack exchange,提问作者user19389593
相关产品推荐
相关产品推荐

