【React】react-router 路由详解

简介: 【React】react-router 路由详解

1.什么是路由

前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做,根据不同的url地址展示不同的内容或页面。

一个针对React而设计的路由解决方案、可以友好的帮你解决React Components 到 URL 之间的同步映射关系。

2.路由安装

npm install react-router-dom@5

react-router-dom 的理解

  1. react 的一个插件库。
  2. 专门用来实现一个SPA应用。
  3. 基于react 的项目基本都会用到此库。

react-router-dom相关API

内置组件

<BrowserRouter> /<HashRouter>/ <Route> /<Link>/ <Switch>

其他

history 对象 / match 对象 / withRouter函数

3.路由使用

基本使用

路由方法导入

import { Link,Route } from 'react-router-dom'

路由链接

<link to="/home">About</link>

to属性的值表示要跳转的路由,react中link就相当于 a 标签。

注册路由

import Home from '...'
...
<Route path="/home" component={Home}></Route>

path属性的值表示 Route 匹配的路由,component属性的值表示与这个路由路径相匹配的组件。

注意: <Link/>标签和 <Route/>标签必须要在 Router的内部写入才生效,且 <Link/> 标签和 <Route/>标签在同一个 Router中。

这里的 Router有两种形式:BrowserRouterHashRouter

BrowserRouter与HashRouter的区别

  1. 底层原理不一样:
  1. BrowserRouter使用的是H5的history API,不兼容IE9及以下的版本。
  2. HashRouter使用的是URL哈希值。
  1. path表现形式不一样:
  1. BrowserRouter的路径中没有#,例如:location:3000/demo/test
  2. HashRouter的路径包含#,例如:location:3000/#/demo/test
  1. 刷新后对路由state参数的影响:

(1). BrowserRouter没有任何影响,因为state保留在history对象中。

(2). HashRouter刷新后会导致state参数的丢失!

4.备注:HashRouter可以用于解决一些路径错误相关的问题。

NavLink的使用

在项目开发中,我们经常遇到 路由切换显示高亮的效果。

如图:

Navlink的作用与上文提到的 <Link>一样,只是又另外提供了一个 activeClassName属性,activeClassName属性指定选中路由的a链接的样式。

import {NavLink} from 'react-router-dom'
<NavLink activeClassName="atguigu">About</NavLink>

Switch的使用

Switch可以提高路由匹配效率(单一匹配)。

路由默认情况下使用的是模糊匹配。比如:

<Route path="/home" component={Home}/>
<Route path="/home/detail" component={Detail}/>

在路由的模糊匹配下,当进入‘xxx/home/detail’这个网址时,路由能同时匹配到 ‘/home’ 和 '/home/detail’两个路由,那么页面上将会同时出现 Home 和 Detail 两个组件的内容。

为了避免这种情况的发生,我们需要把路由写入 标签内,作用是:当路由匹配到一个 path 后,就不再继续向下匹配了。

<Switch>
  <Route path="/home" component={Home}/>
  <Route path="/home/detail" component={Detail}/>
</Switch>

另一种解决办法就是修改 <Route/> 的匹配模式为严格模式

严格模式

<Route path="/home" component={Home} exact>

exact精确匹配{Redirect}即使使用了exact,外面还要嵌套<Switch/>来用。

注意:

严格匹配不要随便开启,有需要再开,因为有时候开启会导致无法继续匹配二级路由。

redirect重定向

<Route exact path="/" component={Home}></Route>
  <Route path="/about" component={About}></Route>
    <Route path="/news" component={News}></Route>
    <Redirect from="/" to="/about"></Redirect>
  <Redirect from="/*" to="/login"></Redirect>

1.当用户访问某个页面的时候, 该页面并不存在,此时需要Redirect 重定向, 重新跳到一个我们一个自定义的组件里边。

<Redirect from="/*" to="/login"></Redirect>

2.如果进入到首页面,首页需要默认展示一些东西(数据)。此时path=’/’,如果什么路由组件都没有匹配到, 就需要Redirect重定向,跳转到要展示的页面。

<Redirect from="/" to="/about"></Redirect>

<Redirect/> 写在<Switch/>标签内,所有的<Route/>路由之后。

向路由组件传参的三种方式

路由组件与一般组件的区别

  1. 写法不同

一般组件:<Demo/>

路由组件:<Route path="/demo" component={Demo}/>

  1. 通常存放位置不同

一般组件: components文件夹下

路由组件: pages文件夹下

3.接收到的props不同:

一般组件:组件标签内写了什么属性,就能收到什么。

路由组件:接收到三个固定的属性

history:{
    ...
    go: f go(n),
    goBack: f goBack(),
    goForward: f goForward(),
    push: f push(path,state),
    replace: f replace(path,state)
},
location:{
    ...
    pathname:'/xxx',
    search:"",   
    state:undefined
},
match:{
    ...
  params: {}
  path: '/xxx'
  url: '/xxx'
}     

1.params参数

路由链接携带参数:

<link to="/demo/test/Tom/18">详情</link>

注册路由:

<Route path="/demo/test/:name/:age" component={Test}/>

路由组件接收参数:

const {name,age} = this.props.match.params

2.search参数

路由链接携带参数:

<link to="/demo/test?name=Tom&age=18">详情</link>

注册路由:

<Route path="/demo/test" component={Test}/>

路由组件接收参数:

const {search} = this.props.location

此时 search=’?name=Tom&age=18’

需要借助querystring, 将获取到的search解析为一个对象。

import qs from 'querystring'
qs.parse(search.slice(1))

3.state参数

路由链接携带参数:

<link to={{path:"demo/test",state:{name:'Tom',age18}}}>详情</link>

注册路由:

<Route path="/demo/test" component={Test}/>

路由组件接收参数:

const {name,age} = this.props.location.state

前两种传参方式,传递的参数在path上有所体现,参数随path的改变而改变。

state传参方式在 BrowserRouter下,只要不清除浏览器缓存,即使页面刷新也可以保留住参数,因为location对象是histoty对象的一部分,也就是说state保存在history中。当使用HashRouter时,页面刷新会造成参数丢失,因为 hashRouter中没有history对象来保存state。

声明式导航与编程式导航

push()

params传参

<Link to={/home/message/detail/${msgobj.id}/${msgobj.title}}>
{msgobj.title}</Link>
this.props.history.push(`/home/message/detail/${id}/${title}`)

search参数

<Link to={/home/message/detail/?id=${msgobj.id}&title=${msgobj.title}}>
{msgobj.title}</Link>
this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)

state传参

<Link to={{`
          `pathname:'/home/message/detail',`
          `state:{id:msgobj.id,title:msgobj.title}`
         `}}>{msgobj.title}</Link>
this.props.history.push(`/home/message/detail`,{id,title})

replace()同理

this.props.history.goBack()后退

this.props.history.goForward()前进

this.props.history.go(num)前进(后退)num步

WithRouter

可以加工一般组件,让一般组件具备路由组件所特有的API。

import { withRouter } from 'react-router-dom'
...
class Header extends Component {
  ...
}
export default withRouter(Header)

WithRouter 返回值是一个新组件。

4.反向代理

安装包

npm install http-proxy-middleware --save

配置文件

在src根目录新建 setupProxy 文件,写入如下代码:

const {createProxyMiddleware} = require('http-proxy-middleware')
module.exports = function(app){
    app.use(
        "/ajax", //我们可以在这里设置个口令  
        createProxyMiddleware({
            target:'http://i.maoyan.com', //target是api服务器地址 
            changeOrigin: true, //这个是是否替换这里一定要写true  
            // 去掉我们添加的前缀,保证我们传递给后端的接口是正常的
            pathRewrite: { "^/api": '' } //这是个正则匹配
        })
    );
};

5.cssModule

场景:由于各个组件内引用的css文件,最终会合并在 /public/index.html的

修改css文件名并引入css文件

import style from'./css/Film.module.css'

只要引入的css文件不同,即使在不同的组件中使用相同的类名如 style.bigbox,最终形成的类名仍不相同。

<div className={style.bigbox}></div>


相关文章
|
3月前
|
前端开发 JavaScript
React项目路由懒加载lazy、Suspense,使第一次打开项目页面变快
本文介绍了在React项目中实现路由懒加载的方法,使用React提供的`lazy`和`Suspense`来优化项目首次加载的速度。通过将路由组件改为懒加载的方式,可以显著减少初始包的大小,从而加快首次加载速度。文章还展示了如何使用`Suspense`组件包裹`Switch`来实现懒加载过程中的fallback效果,并提供了使用前后的加载时间对比,说明了懒加载对性能的提升作用。
233 2
React项目路由懒加载lazy、Suspense,使第一次打开项目页面变快
|
1月前
|
前端开发 API UED
React 路由守卫 Guarded Routes
【10月更文挑战第26天】本文介绍了 React 中的路由守卫(Guarded Routes),使用 `react-router-dom` 实现权限验证、登录验证和数据预加载等场景。通过创建 `AuthContext` 管理认证状态,实现 `PrivateRoute` 组件进行路由保护,并在 `App.js` 中使用。文章还讨论了常见问题和易错点,提供了处理异步操作的示例,帮助开发者提升应用的安全性和用户体验。
51 1
|
4月前
|
移动开发 资源调度 前端开发
介绍React路由模式
【8月更文挑战第10天】介绍React路由模式
63 12
|
1月前
|
前端开发 安全 网络安全
React——路由Route
React——路由Route
35 2
React——路由Route
|
2月前
|
资源调度 前端开发 测试技术
React Router 路由管理
【10月更文挑战第10天】本文介绍了 React Router,一个在 React 应用中管理路由的强大工具。内容涵盖基本概念、安装与使用方法、常见问题及解决方案,如路由嵌套、动态路由和路由守卫等,并提供代码示例。通过学习本文,开发者可以更高效地使用 React Router,提升应用的导航体验和安全性。
301 19
|
2月前
|
前端开发 网络架构
React 路由
10月更文挑战第11天
34 2
|
2月前
|
前端开发 JavaScript 网络架构
实现动态路由与状态管理的SPA——使用React Router与Redux
【10月更文挑战第1天】实现动态路由与状态管理的SPA——使用React Router与Redux
41 1
|
3月前
|
前端开发 Python
React技术栈-React路由插件之自定义组件标签
关于React技术栈中React路由插件自定义组件标签的教程。
62 4
React技术栈-React路由插件之自定义组件标签
|
3月前
|
移动开发 前端开发 应用服务中间件
React两种路由模式的实现原理
React两种路由模式的实现原理
103 3
|
3月前
|
前端开发 程序员 API
React技术栈-React路由插件之react-router的基本使用
这篇博客介绍了React路由插件react-router的基本使用,包括其概念、API、以及如何通过实战案例在React应用中实现SPA(单页Web应用)的路由管理。
81 9