React:无localStorage token时如何隐藏菜单及路由?
问题分析与解决方案
你的核心问题是JSX语法错误(直接在<Routes>内写if语句),以及未同时处理「路由权限控制」和「侧边菜单隐藏」两个需求。以下是具体修复方案:
一、先解决JSX语法错误
JSX中不能直接插入if语句,必须使用条件表达式(三元运算符/逻辑与)来实现条件渲染。
二、完整实现方案
1. 路由权限控制 + 菜单隐藏
通过判断localStorage中是否存在token,分别控制路由渲染和侧边菜单显示:
import { Routes, Route, Navigate } from 'react-router-dom'; import appInfo from './app-info'; import routes from './app-routes'; import { SideNavOuterToolbar as SideNavBarLayout } from './layouts'; import { Footer } from './components'; // 导入你的登录组件(需自行补充路径) import Login from './pages/Login'; export default function Content() { // 统一判断登录状态:转换为布尔值,避免null/空字符串干扰 const isLoggedIn = !!localStorage.getItem('token'); return ( {/* 向布局组件传递登录状态,控制菜单显示 */} <SideNavBarLayout title={appInfo.title} showNav={isLoggedIn}> <Routes> {/* 登录路由始终可见 */} <Route path="/login" element={<Login />} /> {/* 已登录时,渲染所有功能路由 */} {isLoggedIn && routes.map(({ path, element }) => ( <Route key={path} path={path} element={element} /> ))} {/* 404路由:已登录跳首页,未登录跳登录页 */} <Route path="*" element={isLoggedIn ? <Navigate to="/" /> : <Navigate to="/login" />} /> </Routes> <Footer> © Bản quyền: FAMABOOK® 2018 - {new Date().getFullYear()} . </Footer> </SideNavBarLayout> ); }
2. 修改侧边布局组件(控制菜单显示)
需要在SideNavOuterToolbar组件中,根据传入的showNav参数控制菜单渲染:
// layouts/SideNavOuterToolbar.jsx import SideNav from './SideNav'; // 假设你的侧边菜单组件 import Toolbar from './Toolbar'; // 顶部工具栏组件 export default function SideNavOuterToolbar({ title, showNav = true, children }) { return ( <div className="app-layout"> {/* 仅当showNav为true时,渲染侧边菜单 */} {showNav && <SideNav />} <div className="main-content"> <Toolbar title={title} /> {children} </div> </div> ); }
3. 进阶:封装私有路由组件(更规范)
如果路由较多,建议封装PrivateRoute组件统一处理权限:
// components/PrivateRoute.jsx import { Navigate } from 'react-router-dom'; export default function PrivateRoute({ children }) { const isLoggedIn = !!localStorage.getItem('token'); // 未登录则重定向到登录页,已登录则渲染子组件 return isLoggedIn ? children : <Navigate to="/login" replace />; }
然后在Content中使用:
// Content.jsx 中修改路由部分 <Routes> <Route path="/login" element={<Login />} /> {/* 用PrivateRoute包裹所有需要权限的路由 */} {routes.map(({ path, element }) => ( <Route key={path} path={path} element={ <PrivateRoute> {element} </PrivateRoute> } /> ))} <Route path="*" element={<Navigate to="/login" />} /> </Routes>
注意事项
- 前端仅做基础权限控制,实际项目中需结合后端接口验证
token有效性,防止篡改本地存储的token绕过权限。 - 如果登录状态变化(比如登出),需要手动刷新页面或使用状态管理工具(如Redux、Context)同步状态,避免UI不更新。
内容的提问来源于stack exchange,提问作者Đỗ Như Vỹ
相关产品推荐
相关产品推荐

