-
web端使用路由安装的是
react-router-dom"react-router-dom": "^5.2.0"
-
在组件中使用路由,我们先设置2个路由,分别是首页、关于
// src/components/RouteSample.js
import React from 'react';
// 引入路由需要的基础模块
import {BrowserRouter, Link, Route} from 'react-router-dom'export default function RouteSample () {
return (
{/* 导航链接 */} <div><Link to="/">首页</Link></div> <div><Link to="/about">关于</Link></div> {/* 路由配置:路由就是组件 */} <Route path="/" component={Home}></Route> <Route path="/about" component={About}></Route> </div> </BrowserRouter> </div> )}
然后补充首页、关于2个组件,这时页面就可以切换路由了,但是发现一个问题,当路由切换至
about时,首页的内容依然展示在页面上,这是react一个特点叫包容式路由,默认情况是多个组件组成一个页面展示,也就是当我们访问/about时会包含/的内容
"关于"页面.jpg// src/components/RouteSample.js
function Home() {
return
Home
}function About () {
return (
About
)
}接着上面的情况想要改成独占式的路由,也就是一个路由只展示当前组件,我们用到一个属性
exact{/* 路由配置:路由就是组件 */}
react路由也是有动态路由概念的,我们在首页展示一个课程列表,点击分别进入对应的课程详情页,继续在上面的代码基础上扩展// src/components/RouteSample.js
function Home() {
return
Home
- web
- ios
}// src/components/RouteSample.js
{/* 新增详情页路由 lesson就是动态传参的部分*/}
// src/components/RouteSample.js
// 新增详情页组件
// 传递进来的是路由器对象
// 路由器对象主要包含以下3部分,可以结合下面的具体截图理解
// 1. history 导航指令 history.goBack
// 2. match 获取参数信息
// 3. location 当前url信息
function Detail (routeParams) {
console.log('routeParams',routeParams)
return (
当前课程:{routeParams.match.params.lesson}
)
}路由器参数.jpg
-
在开发过程中有时候会碰到所有路由都不匹配的情况,也就是路径不对、页面找不到,通常会给一个404页面,在
react中这样处理,加上404路由之后会发现无论路由在哪个页面404页面会一直显示(如下图),这里又遇到上面同样的问题react路由匹配时包容性质的,这里用到一个新组件Switch,不用像之前给每个组件添加exact属性那么麻烦,路由只会在Switch包裹范围内选1个,修改完之后会发现只有在路由都不匹配的情况下才会显示404页面// src/components/RouteSample.js
// 新增404页面组件 展示访问的具体路径不存在
function NoMatch ({location}) {
return (
404, {location.pathname}不存在
)
}// 新增404路由
{/* 404页面没有path 当有path的路由都不匹配时那必然匹配404*/}
首页展示404.jpg
ios详情页显示404.jpg
// src/components/RouteSample.js import React from 'react'; // 引入Switch import {BrowserRouter, Link, Route, Switch} from 'react-router-dom' {/* 路由配置:路由就是组件 */} {/* 用Switch包裹路由配置,避免展示包容式路由 */} <Switch> <Route exact path="/" component={Home}></Route> <Route path="/about" component={About}></Route> <Route path="/detail/:lesson" component={Detail}></Route> {/* 404页面没有path 当有path的路由都不匹配时那必然匹配404*/} <Route component={NoMatch}></Route> </Switch>路由不存在显示404.jpg
-
接着再研究下路由嵌套,修改一下
About组件,用作展示当前用户信息,分为"个人信息"和"订单信息",按原先的路由结构来看,现在"个人信息"、"订单信息"就是嵌套在About下的,从页面上可以看出这里有一个问题,就是点击"关于"展示About时,没有给嵌套路由默认展示项,必须要手动再次点击"个人信息"或者"订单信息"才能正常显示(默认情况如下图),这时候可以给一个路由重定向作为默认展示的路由,结合vue还是很容易理解的// src/components/RouteSample.js
// 当前用户信息
function About () {
return (
About
个人信息
订单信息
<Route path="/about/me" component={() => (me)}>
<Route path="/about/order" component={() => (order)}>
)
}
about默认不展示嵌套路由内容.jpg
// src/components/RouteSample.js import {BrowserRouter, Link, Route, Switch, Redirect} from 'react-router-dom' <Switch> <Route path="/about/me" component={() => (<div>me</div>)}></Route> <Route path="/about/order" component={() => (<div>order</div>)}></Route> {/* 路由默认项 */} <Redirect to="/about/me"></Redirect> </Switch>-
路由中有一项非常重要的功能是路由守卫,可以用于很多场景,最常见的就是以是否登录判断显示当前访问页面还是跳转登录页,
react中的路由守卫跟vue-router的有很大不同,react是用一个高阶组件扩展<Route>// src/components/RouteSample.js
// 保留路由组件所需的参数component、以及其他参数例如pth等,同时传一个登录状态isLogin
function PrivateRoute ({component: Comp, isLogin, ...rest}) {
return (
// render函数 根据条件动态渲染组件
// 未登录则重定向至登录页
// 登录路由也配置了一个redirect,这样在设计登录组件的时候当登录成功即重定向跳转至登录前访问的页面
<Route
{...rest}
render = {
props => isLogin ? () : (<Redirect
to={{pathname: "/login", state: {redirect: props.location.pathname}}}
>)
}
>
)
} -
然后补充登录组件和路由配置,同时修改
About组件的使用// src/components/RouteSample.js
// 从路由参数拿到重定向地址,从redux获取登录状态和登录方法
function Login ({location, isLogin, login}) {
const redirect = location.state.redirect || '/'
if(isLogin) {
return
}
return (
用户登录
)
}{/* 路由配置:路由就是组件 /}
使用路由守卫 /}
{/
{/ 404页面没有path 当有path的路由都不匹配时那必然匹配404*/}
-
上一步已经实现了路由守卫的逻辑,下一步则补充
redux中关于登录状态以及登录方法异步请求的相关内容,新建redux中的用户模块,路径是src/store/user.redux.js,用户模块添加完成后要在src/store/index.js中完成注册才能使用// src/store/user.redux.js
// 初始化状态,没在登录中 并且 未登录
const initial = {
isLogin: false,
loading: false
}export const user = (state = initial, action) => {
switch(action.type) {
// 登录中
case "requestLogin":
return {
isLogin: false,
loading: true
};
// 已登录
case "login":
return {
isLogin: true,
loading: false
};
default:
return state;
}
}// 请求登录异步调用时,先修改状态为登录中
export const login = () => dispatch => {
dispatch({type: 'requestLogin'});
setTimeout(() => {
dispatch({type: 'login'})
}, 1500);
}// src/store/index.js
// applyMiddleware 应用中间件方法
import {createStore, applyMiddleware, combineReducers} from 'redux';
import logger from 'redux-logger'
import thunk from 'redux-thunk'
import {user} from './user.redux'const store = createStore(
combineReducers({user}),
applyMiddleware(logger, thunk)
);export default store;
-
完成以上模块添加之后再回到路由守卫的部分做对应修改,路由守卫和登录组件都需要用到登录状态值,这里我们使用
react-redux// src/components/RouteSample.js
// 添加引用
import {connect} from 'react-redux';
import {login} from '../store/user.redux'// 路由守卫
const PrivateRoute = connect(
state => ({isLogin: state.user.isLogin})
)(
({component: Comp, isLogin, ...rest}) => {
return (
// render 根据条件动态渲染组件
<Route
{...rest}
render={
props => isLogin ?
() :
(<Redirect
to={{pathname: "/login", state: {redirect: props.location.pathname}}}
>)
}
>
)
}
)// 登录组件
const Login = connect(
// 映射状态与dispatch方法
state => ({
isLogin: state.user.isLogin,
loading: state.user.loading
}),
{login}
)(
({location, isLogin, login, loading}) => {
const redirect = location.state.redirect || '/'
if(isLogin) {
return
}
return (
用户登录
{/* loading优化 */}
)
}
) -
最后需要注意的是使用路由组件时使用方式、引入
store的方式// App.js
import store from './store/index'
import {Provider} from 'react-redux'import RouteSample from './components/RouteSample'
{/* router */}
-
下图展示了整个登录流程发生的记录
登录流程.jpg
© 著作权归作者所有,转载或内容合作请联系作者
喜欢的朋友记得点赞、收藏、关注哦!!!
React - router的使用 && 结合react-redux的路由守卫
荆州克莱2025-01-13 17:00
相关推荐
橘子海全栈攻城狮7 小时前
【最新源码】基于SpringBoot + Vue的超市管理系统的设计与实现D002空中湖7 小时前
Spring AI Function Calling 完全指南:让 AI 查数据库、调 API、发通知风起洛阳@不良使8 小时前
spring中xml和注解开发的对比野蛮人6号8 小时前
黑马天机学堂Day01-08.搭建项目环境-本地开发部署方式——不知道nacos的密码是什么weixin_727535628 小时前
双Token认证体系深度拆解:Spring Security + JWT + Redis拾贰_C8 小时前
【Java | SpringBoot | GlobalExceptionHandler】全局异常拦截器实现思路Lyra_Infra9 小时前
故障排查报告:Spring boot连接 Nacos 异常及启动失败Ethan010710 小时前
spring事务隔离级别,如果数据库设置为RC,spring可以改为RR吗Ethan010710 小时前
详解Spring 事务三大核心接口,以及我们能用它来做什么wuqingshun31415910 小时前
如何理解Spring Boot中的starter?热门推荐
012026年7月AI圈大地震:GPT-5.6被政府限制、Claude入驻Slack、Anthropic自研芯片02GitHub 镜像站点03如何新建文件夹? 电脑新建文件夹的4种方法04幻兽帕鲁 - 服务器管理员权限与 GM 命令完全指南05AI科技热点日报 | 2026年07月01日06国内可直接用、免费额度/永久免费的大模型API清单(含 SiliconFlow、火山、阿里、智谱、百度、Kimi、DeepSeek、DMXAPI 等)07【AI前线观察】2026年国产开源大模型全面横评:从 DeepSeek V4 到 Kimi K3,谁才是开发者的最优选择?08AI 编程 IDE 全景解析 2026:Agent 全面接管开发链路092026 年 AI 大模型 & AI 编程工具实战全总结102026 国产 AI 大模型横评:DeepSeek、通义千问、Kimi、文心一言、星火、豆包谁更能打?