React router升级到v4版本后,不再提供导出
browerHistory
的功能。如果想要在代码中跳转,只能通过组件里的props
中所包含的history
操作,无法完成在组件外通过JS代码跳转的功能。如果想要自己封装一些服务,比如说为AJAX请求添加拦截器的功能,不通过拦截器的请求强制跳转到登陆页面,这种操作就无法实现了。
其实React router已经给出了解决办法,这里要用到一个额外的库 history 具体用法如下:
安装
可以通过npm包管理器安装
1
npm i history --save
或者通过yarn包管理器安装
1
yarn add history
引入
可以通过CommonJS的方式引入
1
const createHistory = require("history").createBrowserHistory
或者通过ES6标准的写法引入
1
import createHistory from "history/createBrowserHistory"
也可以通过
<script>
标签引入1
<script src="history.min.js"></script>
使用
首先创建history对象,通过代码:
1
const history = createHistory()
这里拿到的history对象和在组件中拿到的
this.props.history
的API都是一样的,可以直接使用,不过如果直接写作history.push('/index')
则会只有地址栏的URL变化了,路由却没有切换。正确的用法应该是这样:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30import React, { Component } from "react";
import { BrowserRouter, Router, Route } from "react-router-dom";
import createHistory from "history/createBrowserHistory"
...
const history = createHistory();
class App extends Component {
render() {
return (
<Router history={history}>
<div className="body">
<Route path="/login" component={Login} />
<Route path="/main" render={props => {
return (
<BrowserRouter basename="/main">
<div className="App">
<NavBar />
<SideBar />
<MainPage />
</div>
</BrowserRouter>
);
}} />
</div>
</Router>
)
}
}
history.push('/login');将你需要在外部控制的
<BrowserRouter>
替换为<Router>
,并将创建的history
对象作为props传递给<Router>
组件,这样在外部通过操作history
对象就可以正确跳转了。当然,也可以把
history
单独封装为一个模块,方便其他地方使用:1
2
3
4import createHistory from "history/createBrowserHistory"
const history = createHistory();
export default history;
总结
在react-router v4版本中,官方推荐使用<BrowserRouter>
作为路由,但是由于<BrowserRouter>
没有额外兼容这个库,所以我没有找到使用<BrowserRouter>
作为路由后仍在外部使用代码控制跳转的方法,如果有人知道,可以在下面留言告诉我,不胜感激。