React Router V5
忆往昔,上次使用 React Router 还是v5版本,最近抽工作中的空闲时间,复习了v5版本,将笔记分享于此。
安装
npm install react-router-dom@5 --save
使用
- react-router-dom 有 hash模式 和 history模式 两种
- 类组件 入口文件引入路由组件配置
import React, { Component } from 'react'
import { BrowserRouter as Router, Switch, Redirect, Route } from 'react-router-dom'
import Login from './login'; // 登录页
import Home from './home'; // 首页
import OrderList from './order/List'; // 订单列表页
import OrderDetail from './order/detail'; // 订单详情页
import NotFound from './notFound'; // 404页
class App extends Component {
console.log(this.props)
render() {
return (
<Router>
<Switch>
<Route path="/login" component={Login} />
<Route path="/home" component={Home} />
<Route path="/order/List" component={OrderList} />
// 动态路由
<Route path="/order/:id" component={OrderDetail} />
<Route path="/404" component={NotFound} />
// 重定向到首页
<Redirect path="/" to="/login" exact />
// 匹配不存在的页面时 前往404页面
<Redirect path="*" to="/404"/>
</Switch>
</Router>
)
}
}
export default App
a. BrowserRouter组件:表示全局路由模式为 history 模式
b. Switch组件: 呈现匹配位置的第一个
c. Route组件是渲染组件,根据属性 path 的值,来决定渲染哪个组件
d. Redirect 是用来根据路由地址重定向渲染的组件
- 当安装了 react-router-dom 库后, 在 props 属性上会有挂载上 history ,location, match 等属性。
a. history 属性上带有方法实现路由的跳转
ⅰ. history.push('路由地址') ,跳转到对应的路由地址。
ⅱ. history.go(-1) 回退到上一级地址;history.go(-2) 回退到前两级地址
ⅲ. history.goBack( ) 回退上一级地址
......
b. match 属性 :可以获取动态路由上的传参
举个栗子
在订单详情页通过 this.props.match.params.id 能拿到订单列表页 跳转过来的 订单 id 参数
c. loaction属性:返回当前URL路径 location 的各种信息 和 组件上的 exact 属性表示精确匹配。 因为 组件匹配到一个就会停止的特性,所以一般重定向到首页或者无权限页面的 Redirect 组件都是放到 Switch 组件里的最后面。 - 空路由并不是一个空字符串 '',是一个斜杠 '/'
- 在
和 组件上,除了用 component={..} 来渲染组件,还可以用 render 方法来渲染
举个栗子
登录页面进入首页需要保证 cookie 或者 token 存在才允许跳转到 Home 页,那么就可以在 Route 组件上的 render 方法里进行判断。
...
hanToken() {
return !!this.props.token
}
...
<Route
path="/home"
render= {() => {
return this.hasToken() ? <Home/> : <NotFound/>
}
}
/>
...
注意:使用 render 方法动态渲染后,构建的组件上不再带有 router 有关的属性了 (history ,location, match 等属性),此时可以有两种方法解决
方法一:Route 组件上的 render方法上默认参数里包含有 router 有关的属性,我们手动传递给需要被渲染的组件。
<Route
path="/home"
render = {
(props) => {
return this.hasToken() ? <Home {...props} /> : <NotFound/>
}
}
/>
方法二:在没有路由有关属性的组件上,使用react-router-dom提供的高阶组件 withRouter,将组件传递给 withRouter 方法后,返回的组件就带上了路由有关属性。
import React from 'react'
import { withRouter } from 'react-router-dom'
class Home extends Component {
render(){
<div>首页</div>
}
}
export default withRouter(Home)
装饰器使用高阶组件写法:
import React from 'react'
import { withRouter } from 'react-router-dom'
@withRouter
class Home extends Component {
render(){
<div>首页</div>
}
}
export default Home
没有使用 withRouter 前 Home 组件的props上不存在路由属性
使用 withRouter 后 Home 组件的props上带有了路由属性