点击Logout按钮跳转Login页面异常及App.js路由配置咨询
问题分析与解决方案
你的问题根源在于所有路由都嵌套在Topbar和Sidebar的DOM结构里,所以哪怕访问Login页面,Dashboard的框架(顶部栏、侧边栏)也会被强制渲染出来。下面是具体的修复方案:
1. 重构App.js的路由结构
把登录页面和Dashboard页面拆分成两个独立的路由组:Login路由单独作为顶级路由(不包含任何Dashboard组件),而Dashboard的所有页面路由,统一包裹在包含Topbar和Sidebar的布局中。同时添加路由守卫,确保未登录用户无法直接访问Dashboard页面。
修改后的App.js代码:
import { Router, Routes, Route, Navigate, Outlet } from 'react-router-dom'; // 导入你的Login组件,路径根据实际项目调整 import Login from './components/Login'; function App() { // 这里假设你用localStorage存储登录状态,可根据实际鉴权方式调整 const isLoggedIn = localStorage.getItem('userAuthToken') !== null; return ( <Router> <div className="App"> <Routes> {/* 登录页面:独立于Dashboard布局,无Topbar/Sidebar */} <Route path="/login" element={isLoggedIn ? <Navigate to="/" replace /> : <Login />} /> {/* Dashboard布局路由:包含Topbar和Sidebar,仅对已登录用户开放 */} <Route path="/" element={ isLoggedIn ? ( <> <Topbar /> <div className='container'> <Sidebar /> <div className='others'> <Outlet /> {/* 嵌套路由出口,用来渲染Dashboard子页面 */} </div> </div> </> ) : ( <Navigate to="/login" replace /> {/* 未登录自动跳转到登录页 */} ) } > {/* Dashboard子页面路由 */} <Route index element={<Home />} /> <Route path="createTrip" element={<CreateTrip />} /> <Route path="allTrip" element={<AllTrip />} /> <Route path="driverDetail" element={<DriverDetails />} /> <Route path="myVehicle" element={<MyVehicle />} /> </Route> {/* 404路由:根据登录状态跳转 */} <Route path="*" element={ isLoggedIn ? <Navigate to="/" replace /> : <Navigate to="/login" replace /> } /> </Routes> </div> </Router> ); }
2. 实现Logout按钮功能
在Topbar组件中添加Logout逻辑,点击时清除登录状态并跳转至登录页:
import { useNavigate } from 'react-router-dom'; function Topbar() { const navigate = useNavigate(); const handleLogout = () => { // 清除本地存储的登录状态(比如token、用户信息) localStorage.removeItem('userAuthToken'); // 跳转至登录页,replace避免后退回到Dashboard navigate('/login', { replace: true }); }; return ( <div className="topbar"> {/* 其他Topbar内容(比如用户信息、导航) */} <button onClick={handleLogout} className="logout-btn">Logout</button> </div> ); }
3. Login组件核心逻辑示例
登录成功后存储状态并跳转至Dashboard首页:
import { useNavigate } from 'react-router-dom'; function Login() { const navigate = useNavigate(); const handleLoginSubmit = (e) => { e.preventDefault(); // 这里替换为实际的登录API请求逻辑 const loginSuccess = true; // 模拟登录成功 if (loginSuccess) { // 存储登录凭证到localStorage localStorage.setItem('userAuthToken', 'your_valid_token'); // 跳转至Dashboard首页 navigate('/', { replace: true }); } }; return ( <div className="login-container"> <form onSubmit={handleLoginSubmit}> <input type="text" placeholder="Username" required /> <input type="password" placeholder="Password" required /> <button type="submit">Login</button> </form> </div> ); }
关键说明
- 使用
<Outlet />实现嵌套路由,Dashboard布局作为父路由,子页面会自动渲染在Outlet的位置。 - 通过
isLoggedIn判断用户状态,实现路由守卫:未登录用户访问Dashboard会被重定向到Login,已登录用户访问Login会被重定向到Home。 - Logout时必须清除登录状态(如localStorage中的token),防止用户通过浏览器后退回到Dashboard页面。
内容的提问来源于stack exchange,提问作者Sat
相关产品推荐
相关产品推荐

