首页 > 其他分享 >[react] 路由

[react] 路由

时间:2022-12-21 21:32:46浏览次数:35  
标签:index 匹配 react state 参数 组件 路由


文章目录

  • ​​1. 相关理解​​
  • ​​1.1. SPA的理解​​
  • ​​1.2. 路由的理解​​
  • ​​1.2.1 什么是路由?​​
  • ​​1.2.2 路由分类​​
  • ​​2. react-router-dom相关API​​
  • ​​2.1. 内置组件​​
  • ​​2.2. 其它​​
  • ​​3. 基本路由使用​​
  • ​​3.1. 效果​​
  • ​​3.2. 准备​​
  • ​​3.3 路由的基本使用​​
  • ​​3.4 实现​​
  • ​​3.5 路由组件与一般组件的区别​​
  • ​​3.6 NavLink与封装NavLink​​
  • ​​3.7 Switch的使用​​
  • ​​3.8 解决多级路径刷新页面样式丢失的问题​​
  • ​​3.9 路由的严格匹配与模糊匹配​​
  • ​​3.10 Redirect的使用 【重定向】​​
  • ​​4. 嵌套路由使用​​
  • ​​4.1 效果​​
  • ​​4.2 注意​​
  • ​​4.3 实现​​
  • ​​5. 向路由组件传递参数数据​​
  • ​​5.1 效果​​
  • ​​5.2 具体方法​​
  • ​​方法1. params参数​​
  • ​​方法2. search参数​​
  • ​​方法3. state参数​​
  • ​​代码​​
  • ​​6. 多种路由跳转方式​​
  • ​​6.1 push与replace模式​​
  • ​​6.2 编程式路由导航​​
  • ​​6.3 withRouter的使用​​
  • ​​7. 注意​​
  • ​​BrowserRouter与HashRouter的区别​​

1. 相关理解

1.1. SPA的理解

单页Web应用(single page web application,SPA)
整个应用只有一个完整的页面。
点击页面中的链接不会刷新页面,只会做页面的局部更新。
数据都需要通过ajax请求获取, 并在前端异步展现。

1.2. 路由的理解

1.2.1 什么是路由?

一个路由就是一个映射关系(key: value)
key为路径, value可能是function或component

1.2.2 路由分类

1. 后端路由

理解: ​​value​​​是​​function​​, 用来处理客户端提交的请求。

注册路由:​​router.get(path, function(req, res))​

工作过程:当​​node​​接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据

[react] 路由_SPA


2. 前端路由

浏览器端路由,​​value​​​是​​component​​,用于展示页面内容。

注册路由: ​​<Route path="/test" component={Test}>​​​ 工作过程:当浏览器的path变为/test时, 当前路由组件就会变为​​Test​​组件

路由原理history

[react] 路由_SPA_02


[react] 路由_Test_03

[react] 路由_Test_04

[react] 路由_API_05

2. react-router-dom相关API

2.1. 内置组件

<BrowserRouter>
<HashRouter>
<Route>
<Redirect>
<Link>
<NavLink>
<Switch>

2.2. 其它

history对象
match对象
withRouter函数

3. 基本路由使用

3.1. 效果

[react] 路由_Test_06

3.2. 准备

下载react-router-dom:
​​​npm install react-router-dom​

引入bootstrap.css:
​​​<link rel="stylesheet" href="/css/bootstrap.css">​

3.3 路由的基本使用

  1. 明确好界面中的导航区、展示区
  2. 导航区的a标签改为Link标签
    ​​​<Link to="/xxxxx">Demo</Link>​
  3. 展示区写Route标签进行路径的匹配
    ​​​<Route path='/xxxx' component={Demo}/>​
  4. ​<App>​​​的最外侧包裹了一个​​<BrowserRouter>​​​或​​<HashRouter>​

3.4 实现

[react] 路由_react.js_07


[react] 路由_SPA_08


[react] 路由_react.js_09

[react] 路由_react.js_10


[react] 路由_SPA_11


[react] 路由_react.js_12

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

写法不同:
一般组件:​​​<Demo/>​​​ 路由组件:​​<Route path="/demo" component={Demo}/>​​ 存放位置不同:
一般组件:​​components​​ 路由组件:​​pages​​ 接收到的props不同:
一般组件:写组件标签时传递了什么,就能收到什么
路由组件:接收到三个固定的属性

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

3.6 NavLink与封装NavLink

NavLink可以实现路由链接的高亮,通过​​activeClassName​​​属性指定样式名,默认是​​"active"​

<NavLink activeClassName="demo" className="list-group-item" to="/home">Home</NavLink>

可以自己封装一个NavLink【一般组件】
标签体内容是特殊的标签属性,通过this.props.children可以获取标签体内容

import React, { Component } from 'react'
import {NavLink} from 'react-router-dom'

export default class MyNavLink extends Component {
render() {
// console.log(this.props);
return (
<NavLik activeClassName="demo" className="list-group-item" {...this.props} />
)
}
}

[react] 路由_Test_13


this.props等于{to:’/about’,a:1,b:2,c:3,children:“About”}

[react] 路由_API_14


[react] 路由_react.js_15

[react] 路由_Test_16

3.7 Switch的使用

通常情况下,path和component是一一对应的关系。
Switch可以提高路由匹配效率(单一匹配)。

<Switch>
<Route path="/about" component={About}/>
<Route path="/home" component={Home}/>
<Route path="/home" component={Test}/>
</Switch>

这样只要匹配到了第一个就不会再往下匹配了

3.8 解决多级路径刷新页面样式丢失的问题

  1. ​public/index.html​​​ 中 引入样式时不写​​./​​​ 写​​/​​(常用)【绝对路径】

[react] 路由_API_17


2. ​​public/index.html​​​ 中 引入样式时不写​​./​​​写 ​​%PUBLIC_URL%​​(常用)

[react] 路由_Test_18


3. 使用​​HashRouter​

[react] 路由_API_19

3.9 路由的严格匹配与模糊匹配

  1. 默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致)
  2. [react] 路由_API_20

  3. 开启严格匹配:​​<Route exact={true} path="/about" component={About}/>​
  4. [react] 路由_SPA_21

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

3.10 Redirect的使用 【重定向】

  1. 一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
  2. 具体编码:
<Switch>
<Route path="/about" component={About}/>
<Route path="/home" component={Home}/>
<Redirect to="/about"/>
</Switch>

4. 嵌套路由使用

4.1 效果

[react] 路由_react.js_22


[react] 路由_react.js_23

4.2 注意

  1. 注册子路由时要写上父路由的path值
  2. 路由的匹配是按照注册路由的顺序进行的

4.3 实现

[react] 路由_SPA_24

src\index.js

[react] 路由_API_25


APP.js

[react] 路由_react.js_26

src\components\MyNavLink\index.jsx

[react] 路由_API_27


src\pages\About\index.jsx

[react] 路由_API_28

src\pages\Home\index.jsx

[react] 路由_Test_29

src\pages\Home\News\index.jsx

[react] 路由_SPA_30


src\pages\Home\Message\index.jsx

[react] 路由_Test_31

[react] 路由_SPA_32


[react] 路由_Test_33

5. 向路由组件传递参数数据

5.1 效果

[react] 路由_Test_34

[react] 路由_API_35

5.2 具体方法

方法1. params参数

  1. 路由链接(携带参数):
    ​​​<Link to='/demo/test/tom/18'}>详情</Link>​
  2. 注册路由(声明接收):
    ​​​<Route path="/demo/test/:name/:age" component={Test}/>​
  3. 接收参数:​​this.props.match.params​

[react] 路由_API_36

[react] 路由_react.js_37

src/index.js

[react] 路由_react.js_38


src/App.jsx

[react] 路由_SPA_39

src\pages\Home\index.jsx

[react] 路由_API_40


src\pages\Home\Message\index.jsx

[react] 路由_API_41

src\pages\Home\Message\Detail\index.jsx

[react] 路由_API_42


[react] 路由_Test_43

方法2. search参数

  1. 路由链接(携带参数):
    ​​​<Link to='/demo/test?name=tom&age=18'}>详情</Link>​
  2. 注册路由(无需声明,正常注册即可):
    ​​​<Route path="/demo/test" component={Test}/>​
  3. 接收参数:​​this.props.location.search​

备注:获取到的​​search​​​是​​urlencoded​​​编码字符串,需要借助​​querystring​​解析

[react] 路由_SPA_44


[react] 路由_react.js_45

[react] 路由_react.js_46

[react] 路由_Test_47

import qs from 'querystring'
let obj = {name:'tom', age:18}
console.log(qs.stringify(obj)) // name=tom&age=18

let str = 'carName=Benz&price=199'
console.log(qs.parse(str)) // {carName: 'Benz', price: 199}

方法3. state参数

  1. 路由链接(携带参数):
<Link to={{ pathname:'/demo/test', state:{name:'tom',age:18} }}>详情</Link>
  1. 注册路由(无需声明,正常注册即可):
    ​​​<Route path="/demo/test" component={Test}/>​
  2. 接收参数:​​this.props.location.state​​​ 备注:刷新也可以保留住参数【​​history​​对象记录着在】

[react] 路由_SPA_48

[react] 路由_API_49

[react] 路由_SPA_50


[react] 路由_API_51

代码

Message/index.jsx

export default class Message extends Component {
render() {
const {messageArr} = this.state
return (
<div>
<ul>
{
messageArr.map((msgObj)=>{
return (
<li key={msgObj.id}>

{/* 向路由组件传递params参数 */}
{/* <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> */}

{/* 向路由组件传递search参数 */}
{/* <Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link> */}

{/* 向路由组件传递state参数 */}
<Link to={{pathname:'/home/message/detail',state:{id:msgObj.id,title:msgObj.title}}}>{msgObj.title}</Link>

</li>
)
})
}
</ul>
<hr/>
{/* 声明接收params参数 */}
{/* <Route path="/home/message/detail/:id/:title" component={Detail}/> */}

{/* search参数无需声明接收,正常注册路由即可 */}
{/* <Route path="/home/message/detail" component={Detail}/> */}

{/* state参数无需声明接收,正常注册路由即可 */}
<Route path="/home/message/detail" component={Detail}/>
</div>
)
}
}

Detail/index.jsx

import React, { Component } from 'react'
// import qs from 'querystring'

export default class Detail extends Component {
render() {
console.log(this.props);

// 接收params参数
// const {id,title} = this.props.match.params

// 接收search参数
// const {search} = this.props.location
// const {id,title} = qs.parse(search.slice(1))

// 接收state参数
const {id,title} = this.props.location.state || {}

const findResult = DetailData.find((detailObj)=>{
return detailObj.id === id
}) || {}
return (
<ul>
<li>ID:{id}</li>
<li>TITLE:{title}</li>
<li>CONTENT:{findResult.content}</li>
</ul>
)
}
}

6. 多种路由跳转方式

6.1 push与replace模式

默认就是Pushs模式

开启repalce模式

[react] 路由_API_52

6.2 编程式路由导航

借助​​this.prosp.history​​对象上的API对操作路由跳转、前进、后退

  • ​this.prosp.history.push()​
  • ​this.prosp.history.replace()​
  • ​this.prosp.history.goBack()​
  • ​this.prosp.history.goForward()​
  • ​this.prosp.history.go()​
  • [react] 路由_react.js_53


  • [react] 路由_API_54


[react] 路由_react.js_55

6.3 withRouter的使用

export default withRouter(Header)

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

withRouter的返回值是一个新组件

[react] 路由_SPA_56

[react] 路由_react.js_57

[react] 路由_Test_58

7. 注意

BrowserRouter与HashRouter的区别

  1. 底层原理不一样:
    ​BrowserRouter​​使用的是​​H5​​的​​history API​​,不兼容​​IE9​​及以下版本。
    ​HashRouter​​使用的是​​URL​​的哈希值。
  2. ​path​​​表现形式不一样
    ​BrowserRouter​​的路径中没有#,例如:​​localhost:3000/demo/test​​​​HashRouter​​的路径包含#,例如:​​localhost:3000/#/demo/test​
  3. 刷新后对路由​​state​​参数的影响
    (1) ​​BrowserRouter​​没有任何影响,因为​​state​​保存在​​history​​对象中。
    (2)​​HashRouter​​刷新后会导致路由​​state​​参数的丢失!!!
  4. 备注:​​HashRouter​​可以用于解决一些路径错误相关的问题。

[react] 路由_SPA_59

[react] 路由_API_60




参考:
​【React】SPA - 路由机制 - react-router-dom - 基本路由 - 嵌套路由 - 传递参数 - 路由跳转​​


标签:index,匹配,react,state,参数,组件,路由
From: https://blog.51cto.com/u_12881709/5960146

相关文章

  • [react] 表单 受控组件 非受控组件
    文章目录​​收集表单数据​​​​1理解​​​​2应用​​​​3非受控组件​​​​4受控组件​​收集表单数据1理解包含表单的组件分类受控组件非受控组件2应用需求:......
  • TP6在路由文件中同时使用跨域和中间件引起的跨域失败问题的解决过程
    在TP6文档中,写路由文件可以连贯操作middleware和allowcrossdomain,并且里面可以配置参数,我一偷懒,就两个都用了,如下图,之前没有增加Middleware的时候好使,能跨域,但后来要用中间......
  • vue-router3,点击相同的路由,会报错NavigationDuplicated
    vue-router点击相同的路由链接会报错NavigationDuplicated{"_name":"NavigationDuplicated","name":"NavigationDuplicated","message":"Navigatingto......
  • [React] Valtio proxy-state management lib intro
    https://bestofjs.org/projects/valtioCoolthingsaboutValtio,itiscompletelyindependfromReactcomponent.ItisselftestableandhookwithReactverywel......
  • [React] State and Callbacks Don’t Mix Well in React
    //Doesn'tworkimportReactfrom'react'import{saveInfo}from'./api'exportdefaultfunctionApp(){const[count,setCount]=React.useState(0)......
  • vue3 + ts 路由换标题
    npminstallvue-wechat-title--save//引入换标题的插件importVueWechatTitlefrom'vue-wechat-title'//使用插件VueWechatTitleapp.use(store).use(router)......
  • Vue路由配置项meta使用
    meta简单来说就是路由元信息也就是每个路由身上携带的信息。这里简单的举两个例子其次还有一个功能就是能够控制公共组件的显示或隐藏请忽视keep-alive标签......
  • react页面登录重定向中遇到的困惑
    是这样的模拟写了一点后端json数据点击登录跳转到首页,目的是我开启,node服务之前,务必进到登录页首页数据是拿到了。请求是发起异步请求,数据也打印出来了。问题是,路由......
  • 数据库路由器 ICX
    实时并发数据库事务处理同步复制器和负载平衡器   ———通向真正数据库高可用性,高可靠性,高性能之路一、产品概述   数据库路由器--ICX是美国宾夕法尼亚大学计算机......
  • 动态路由rip
    实验拓扑实验配置R1(config)#interfacef0/0R1(config-if)#ipadR1(config-if)#ipaddress172.168.1.1255.255.255.0R1(config-if)#noshuR1(config-if)#noshutdownR1(c......