React路由设置默认登录页及多组件未登录访问拦截问题咨询
问题1:设置localhost默认访问地址为http://localhost:3000/login
直接在路由规则中新增根路径重定向规则即可,不需要修改服务端配置:
- 从
react-router-dom引入Redirect组件 - 在
<Switch>标签下的最上方新增如下路由:
<Route exact path="/"> <Redirect to="/login" /> </Route>
加exact属性是为了避免根路径规则拦截所有子路径的匹配,后续访问localhost:3000会自动跳转到登录页。
问题2:拦截未登录管理员访问受保护组件
现有写法异常原因
你直接将受保护路由包裹在admin && <></>中的写法存在两个缺陷:
- 页面刷新时,redux的用户状态需要从本地存储读取并初始化,初始渲染阶段
admin为undefined,此时受保护路由不会挂载,等状态更新后才会重新渲染,过程中手动输入地址可能出现匹配异常 - 没有配置未登录的跳转逻辑,admin为false时受保护路由直接消失,没有触发登录页跳转,极端场景下会出现路由匹配混乱导致组件被意外渲染
解决方案:封装统一的私有路由组件
单独封装权限校验路由组件,所有需要管理员权限的路由都用该组件包裹,不用逐个添加判断逻辑:
第一步:新建私有路由组件
// src/components/ProtectedRoute.js import { Route, Redirect } from 'react-router-dom'; import { useSelector } from 'react-redux'; const ProtectedRoute = ({ children, ...rest }) => { const admin = useSelector((state) => state.user?.currentUser?.isAdmin); return ( <Route {...rest} render={({ location }) => admin ? ( children ) : ( <Redirect to={{ pathname: "/login", // 携带当前路径,登录后可以直接跳回用户原本要访问的页面 state: { from: location } }} /> ) } /> ); }; export default ProtectedRoute;
第二步:修改App组件代码
替换原有受保护路由的写法,删除admin &&的条件包裹:
import { useSelector } from 'react-redux' import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom' import './App.css' import Sidebar from './components/sidemenu/Sidebar' import Home from './pages/home/Home' import Login from './pages/login/Login' import NewProduct from './pages/newProduct/NewProduct' import NewUser from './pages/newUser/NewUser' import ProductList from './pages/product/ProductList' import Product from './pages/productItem/Product' import User from './pages/user/User' import UserList from './pages/userList/UserList' // 引入封装好的私有路由 import ProtectedRoute from './components/ProtectedRoute' function App() { return ( <Router> <Switch> <Route exact path="/login"> <Login /> </Route> {/* 根路径重定向到登录页 */} <Route exact path="/"> <Redirect to="/login" /> </Route> {/* 所有受保护的路由统一放在ProtectedRoute下 */} <ProtectedRoute path='*'> <div className="container"> <Sidebar /> <Switch> <Route path="/home"> <Home /> </Route> <Route path="/users"> <UserList /> </Route> <Route path="/user/:userId"> <User /> </Route> <Route path="/newUser"> <NewUser /> </Route> <Route path="/products"> <ProductList /> </Route> <Route path="/products/:productId"> <Product /> </Route> <Route path="/newproduct"> <NewProduct /> </Route> </Switch> </div> </ProtectedRoute> </Switch> </Router> ) } export default App
修改后所有非登录路径都会先经过权限校验,未登录的用户不管输入什么受保护地址都会自动跳转到登录页,同时支持登录后跳转回原访问路径。
内容的提问来源于stack exchange,提问作者s_sldiblood
相关产品推荐
相关产品推荐

