安装
cnpm install react-router-dom
import React from 'react'
import Home from './pages/Home'
import Detail from './pages/Detail'
// import {BrowserRouter as Router, Link, Route, Switch} from 'react-router-dom'
import {HashRouter as Router, NavLink, Redirect, Route, Switch, withRouter} from 'react-router-dom'
/**
* BrowserRouter: H5特性, history.push
* HashRouter: 锚点特性,链接里带#号,上线之后需要后台做重定向处理,否则会有404问题
*/
<BrowserRouter
basename={string}
forceRefresh={bool}
getUserConfirmation={func}
keyLength={number}
></BrowserRouter>
1. basename: string 所有位置的基准 URL。如果你的应用程序部署在服务器的子目录,则需要将其设置为子目录。basename 的正确格式是前面有一个前导斜杠,但不能有尾部斜杠。
<BrowserRouter basename="/calendar">
<Link to="/today" />
</BrowserRouter>
2. forceRefresh: bool
如果为 true ,在导航的过程中整个页面将会刷新。一般情况下,只有在不支持 HTML5 history API 的浏览器中使用此功能。
const supportsHistory = 'pushState' in window.history;
<BrowserRouter forceRefresh={!supportsHistory} />
<HashRouter></HashRouter>
1.hashType: string
slash - 后面跟一个斜杠,例如 #/ 和 #/sunshine/lollipops
noslash - 后面没有斜杠,例如 # 和 #sunshine/lollipops
hashbang - Google 风格的 ajax crawlable,例如 #!/ 和 #!/sunshine/lollipops
function App () {
return (
<div className="app">
<Router>
<Switch>{/*使用switch后,每次只加载一个组件*/}
<Route path="/home" component={Home} />
<Route exact path="/detail" component={Detail} />
<Route strict exact path="/detail/:id?" component={Detail} />
{/*可通过render形式给定组件,并且可以传参到demo组件,使用props获取*/ }
<Route path="/demo" render={(props) => <Demo {...props} title="demo" />} />
{/**跳转 */}
<NavLink to='/detail'></NavLink>
{/* 下面这种形式的跳转,state内属于隐形传参,不会再url上显示出来 */}
<NavLink
exact
to={{
pathname: '/detail',
search: '?id=1',
hash: '@hash',
state: {title: 1111}
}}
></NavLink>
{/* url重定向,url访问/oldPage,直接跳到/page去 */}
<Route from="/oldPage" to="/page" />
{/* 进入到页面,判断是否登录,没登录直接跳转到登录页面 */}
<Route path="/shop" render={() => {
return isLogin ? <Shop /> : <Login />
}} />
{/* 或者在Shop页面渲染组件内容的时候做下判断 */}
render () {
return (
<div>
isLogin ? <div>shop内容</div> : <Redirect to="/login">
</div>
)
}
{/* 404 页面配置 */}
<Route component={page404} />
{/* 路由嵌套.在book组件内使用this.props.children加载对应的路由嵌套 */}
<Book>
<Switch>
<Route path="/book/webbook" component={Webbook} />
<Route path="/book/jababook" component={JavaBook} />
</Switch>
</Book>
</Switch>
</Router>
</div>
)
}
export default App
关于url传参部分,传参方式分两种
1,'/detail/1/2'
这种情况需要现在路由配置种做下配置<Route strict exact path="/detail/:id?/val" component={Detail} />,
然后在跳转之后的页面中从props.params中读取id和val
2,'/detail?id=1'
在跳转后的页面种使用以下两种方式获取
1>
const params = new URLSearchParams(props.location.search)
console.log(params.get('id'))
2> 使用qs库
const value = qs.parse(props.location.search)
console.log(value.id)
函数式跳转push/replace(区别:push属于叠加的,上个页面还会存在,replace是覆盖,上一个页面已经不存在)
props.history.push('/shop')
高阶函数 withRouter
作用是将一个组件包裹进Route里面, 然后react-router的三个对象history, location, match就会被放进这个组件的props属性中.
把不是通过路由切换过来的组件中,将react-router 的 history、location、match 三个对象传入props对象上
1. 默认情况下必须是经过路由匹配渲染的组件才存在this.props,才拥有路由参数,才能使用编程式导航的写法,执行this.props.history.push('/ ')跳转到对应路由的页面
然而不是所有组件都直接与路由相连(通过路由跳转到此组件)的,当这些组件需要路由参数时,使用withRouter就可以给此组件传入路由参数,此时就可以使用this.props
2. 高阶组件中的withRouter, 作用是将一个组件包裹进Route里面, 然后react-router的三个对象history, location, match就会被放进这个组件的props属性中.此时这个组件就具备了路由的属性
使用方式很简单
import {withRouter} from 'react-router-dom'
class Shop from Reach.Component {
constructor (props) {
super(props)
props.history.listen(e => {
console.log(e)
// 监测到了路由变化了,当路由变化的时候可以做些可能需要的逻辑
})
}
}
export default withRouter(Shop)