下载
pnpm add react-router-dom@5 //版本5
pnpm add react-router-dom //版本6
路由链接
<Link to="/about">About</Link> // 跳转about路由的组件
注册路由
<Route path="/about" component={About} /> // 匹配的路径path 匹配的组件component
路由模式
通过在app.js中书写路由包裹组件,保证每个组件包裹在同一路由模式下
<BrowserRouter><App /></BrowserRouter> // history模式
<HashRouter><App /></HashRouter> // hash模式
路由组件和一般组件
一般组件存放在components下,路由组件存放在pages下
一般组件直接在页面使用渲染,路由组件通过Router标签的component属性使用
一般组件接收传递的props值,路由组件接收路由器的属性值
NavLink
通过activeClassName属性设置追加的选中类
<NavLink activeClassName="activeClass" to="/about">About</NavLink>
// NavLink封装成一个组件
// 调用
<MyNavLink to="/about">About</MyNavLink>
// 组件 通过解构赋值的方法将参数传递给NavLink
<NavLink activeClassName="activeClass" className="list-group-item" {...this.props} />
多级路由样式丢失
当路由为多级路由时,会出现刷新样式丢失的情况,将路由当做请求地址,造成找不到资源的情况
解决方法:
- public样式引用路径使用“/css/xxx.css”
- public样式引用路径使用“%PUBLIC_URL%/css/xxx.css”,不全路径
- public样式引用路径使用“./css/xxx.css”,使用HashRouter模式,使切换路由不会请求服务器,hash值改变,页面变化
模糊匹配和精准匹配
- 模糊匹配
默认匹配方式
<Link to="/about/a/b">About</Link> //会匹配到About组件
<Route path="/about" component={About} />
- 精准匹配
使用exact开启精准匹配
<Link to="/about/a/b">About</Link>
<Route exact path="/about/a/b" component={About} />
// 只有路径path和Link跳转to保持一致时,才会匹配到About组件
Redirect
当注册路由没有匹配的路由时,进行Redirect重定向
<Redirect to="/about" />
嵌套路由
当需要嵌套路由时,需要将路由以写全的方式形成多级路由,进行路由的匹配
<MyNavLink to="/home/news">News</MyNavLink>
<Route path="/home/news" component={News} />
路由传参
// 父组件
<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>
// 子组件
import React, { Component } from 'react'
import qs from 'querystring-es3' // webpack5之前使用querystring无需安装,webpack5之后使用querystring-es3需要安装
const detailData = [
{ id: '01', content: '内容1' },
{ id: '02', content: '内容2' },
{ id: '03', content: '内容3' }
]
export default class Detail extends Component {
render() {
// 接收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>
)
}
}
push
向栈中存入一个路由记录,保存历史路由
replace
替换当前路由
编程式路由
this.props.history.replace()
this.props.history.push()
this.props.history.goBack()
this.props.history.goForward()
this.props.history.go()
withRouter
将一般组件进行加工,使一般组件具有路由组件api
返回加工后的新组件
在React中,使用withRouter高阶组件可以让你在组件中访问路由信息,例如当前路由的路径、查询参数等。这样你就可以根据路由信息来执行相应的操作,比如根据路径改变导航栏的当前选项等。
要使用withRouter,你需要先安装react-router-dom库。安装完成后,可以通过以下步骤使用withRouter:
- 在你的组件中导入
withRouter:
import withRouter from 'react-router-dom/withRouter';
- 将你的组件包装在
withRouter函数中:
const MyComponent = withRouter(({ match, location }) => {
// 在这里访问路由信息
const path = match.path;
const query = match.url.query;
// ...
});
现在你的组件就可以访问路由信息了。你可以使用match属性来访问当前路由的信息,包括路径、查询参数等。还可以使用location属性来访问当前的URL信息,例如路径和查询参数。
注意,withRouter会将路由信息作为props传递给组件,因此你可以在组件中使用这些props来访问路由信息。
browserRouter和hashRouter
底层原理不同:
browserRouter使用的是history API,hashRouter使用的是url的hash值
表现形式不同:
hashRouter的url带有#的哈希值
刷新后starte参数影响:
browerRouter没有影响,state保存在history中
hashRouter刷新会导致state参数丢失