React-Router
最新的路由的版本是5.1.2的版本。里面的话提供了一些包 (react-router-native等)
所在在做web端开发的时候只需要安装react-router-dom就可以了,因为内部已经包含了最核心的内容了。
路由的简单使用
安装路由: yarn add react-router-dom
需要在最外层的节点上面:
//HashRrouter hash值
//BrowerBrouter history模式
import {HashRouter as Router} from "react-router-dom"
ReactDOM.render(
<Router>
<App />
</Router>
,
document.getElementById('root')
);
使用Route实现路由组件与路径的对应切换效果
import React, { Component } from 'react'
import {Route,Redirect,Switch} from "react-router-dom"
import Home from "./views/Home"
import Article from "./views/Article"
import NotFound from "./views/NotFound"
//通过Route组件,可以进行路由访问了
//Route里面的path代表路径,component代表映射的路由组件
//Switch代表内部的Route只会匹配一个,匹配到了就不会向下执行
//Redirect代表重定向,to代表跳到目标路由地址,from代表来自哪个路径 (默认内部不是完全匹配的)
//exact属性代表url地址栏的路径与Route的path完全一致的时候,component才会渲染。
export default class App extends Component {
render() {
return (
<div>
<Switch>
<Route path="/home" component={Home}/>
<Route path="/article" component={Article} />
<Route path="/404" component={NotFound}/>
<Redirect to="/home" from="/" exact/>
<Redirect to="/404"/>
</Switch>
</div>
)
}
}
可以通过NavLink实现a标签的切换效果,渲染成a标签,并且带有active的class样式
import {Route,Redirect,Switch,NavLink as Link} from "react-router-dom"
<ul>
<li><Link to="/home">首页</Link></li>
<li><Link to="/article">文章列表</Link></li>
</ul>
二级路由与动态跳转
二级路由:
<ul>
<li><Link to="/home">首页</Link></li>
<li><Link to="/article">文章列表</Link></li>
</ul>
<Switch>
<Route path="/home" component={Home}/>
<Route path="/article" component={Article} exact/> /article/1
<Route path="/article/:id" component={ArticleDetail}/>
<Route path="/404" component={NotFound}/>
<Redirect to="/home" from="/" exact/>
<Redirect to="/404"/>
</Switch>
路由常用的api方法
render函数
一旦通过Route组件的component属性指明的组件,那么这个路由组件上面就会有路由相关的api
(location / history / match)
如果必须要传入属性的话,单纯使用component是解决不了的。
<Route path="/home" render={(routeProps)=>{
return this.state.isLogin?<Home x={1} {...routeProps}/>:"未登录"
}}/>
link的参数传递
1.可以通过动态路由的方式进行参数传递
path="/detail/:id"
Detail组件内部可以通过 this.props.match.params.id可以获取到动态参数
2.可以通过query进行传参
path="/detail?title=文章一"
Detail组件内部可以通过 this.props.location.search可以获取到 “?title=文章一”
3.可以通过state进行隐式传参
to={{pathname:’/detail/2’,state:{title:‘文章2’}}}
Detail组件内部可以通过 this.props.location.state.title可以获取到
withRouter
默认的BackHome组件只是一个普通组件,默认没有history/location/match相关的api,所以封装的backhome组件调用this.props.history就会报错。
为啥articleDetail里面调用this.props.history不会出错呢?
那是因为,所以的话articleDetail是路由组件,就会通过属性获取到路由相关的api了。
而BackHome它又不是路由组件,所以才会报错。如何不让他报错呢?
我们可以通过引入高阶组件withRouter,将普通组件进行包裹,那么BackHome就变成了伪路由组件,它本身不能实现跳转,但是仍然可以通过属性去访问到路由相关的api了。
import React, { Component } from 'react'
import {withRouter} from "react-router-dom"
//因为当前的组件不是路由组件,因为没有通过Route进行包裹指明。
class BackHome extends Component {
backHome = ()=>{
console.log("backhome",this.props)
// this.props.history.push("/home")
this.props.history.push({
pathname:"/home",
state:{
id:"哈哈哈"
}
})
}
render() {
return (
<div>
<button onClick={this.backHome}>返回首页</button>
</div>
)
}
}
export default withRouter(BackHome)