react-routerv4如何使⽤history控制路由跳转详解
前⾔
距离React Router v4 正式发布也已经挺久了,这周把⼀个React的架⼦做了升级,之前的路由⽤的还是v2.7.0版的,所以决定把路由也升级下,正好“尝尝鲜”...
江湖传⾔,⽬前官⽅同时维护 2.x 和 4.x 两个版本。(ヾ(。ꏿ﹏ꏿ)  咦,此刻相信机智如我的你也会发现,ReactRouter v3 去哪⼉了?整丢了??巴拉出锅了敢不敢给我个完美的解释!?)事实上 3.x 版本相⽐于 2.x 并没有引⼊任何新的特性,只是将 2.x 版本中部分废弃 API 的 warning 移除掉⽽已。按照规划,没有历史包袱的新项⽬想要使⽤稳定版的 ReactRouter 时,应该使⽤ ReactRouter 3.x。⽬前 3.x 版本也还处于 beta 阶段,不过会先于 4.x 版本正式发布。如果你已经在使⽤ 2.x 的版本,那么升级 3.x 将不会有任何额外的代码变动。
问题
当我们使⽤react-router v3的时候,我们想跳转路径,我们⼀般这样处理
我们从react-router导出browserHistory。
我们使⽤browserHistory.push()等等⽅法操作路由跳转。
类似下⾯这样
import browserHistory from 'react-router';
export function addProduct(props) {
return dispatch =>
axios.post(`xxx`, props, config)
.then(response => {
browserHistory.push('/cart'); //这⾥
});
}
but!! 问题来了,在react-router v4中,不提供browserHistory等的导出~~
那怎么办?我如何控制路由跳转呢
解决⽅法
1. 使⽤ withRouter
withRouter⾼阶组件,提供了history让你使⽤~
import React from "react";
import {withRouter} from "react-router-dom";
class MyComponent extends React.Component {
...
myFunction() {
this.props.history.push("/some/Path");
}
...
}
export default withRouter(MyComponent);
这是官⽅推荐做法哦。但是这种⽅法⽤起来有点难受,⽐如我们想在redux⾥⾯使⽤路由的时候,我们只能在组件把history传递过去。。
就像问题章节的代码那种场景使⽤,我们就必须从组件中传⼀个history参数过去。。。
2. 使⽤ Context
react-router v4 在 Router 组件中通过Contex暴露了⼀个router对象~
在⼦组件中使⽤Context,我们可以获得router对象,如下⾯例⼦~
import React from "react";
import PropTypes from "prop-types";
class MyComponent extends React.Component {
static contextTypes = {
router: PropTypes.object
}
constructor(props, context) {
super(props, context);
}
...
myFunction() {
}
...
}
当然,这种⽅法慎⽤~尽量不⽤。因为react不推荐使⽤contex哦。在未来版本中有可能被抛弃哦。
3. hack
其实分析问题所在,就是v3中把我们传递给Router组件的history⼜暴露出来,让我们调⽤了~~
⽽react-router v4 的组件BrowserRouter⾃⼰创建了history,并且不暴露出来,不让我们引⽤了。尴尬~
我们可以不使⽤推荐的BrowserRouter,依旧使⽤Router组件。我们⾃⼰创建history,其他地⽅调⽤⾃⼰创建的history。看代码~
我们⾃⼰创建⼀个history
// src/history.js
import createHistory from 'history/createBrowserHistory';
export default createHistory();
我们使⽤Router组件
// src/index.js
import { Router, Link, Route } from 'react-router-dom';react router路由传参
import history from './history';
<Provider store={store}>
<Router history={history}>
...
</Router>
</Provider>,
);
其他地⽅我们就可以这样⽤了
import history from './history';
export function addProduct(props) {
return dispatch =>
axios.post(`xxx`, props, config)
.then(response => {
history.push('/cart'); //这⾥
});
}
4. 我⾮要⽤BrowserRouter
确实,react-router v4推荐使⽤BrowserRouter组件,⽽在第三个解决⽅案中,我们抛弃了这个组件,⼜回退使⽤了Router组件。
怎么办。你去看看BrowserRouter的,我觉得你就豁然开朗了。
源码⾮常简单,没什么东西。我们完全⾃⼰写⼀个BrowserRouter组件,然后替换第三种解决⽅法中的Router组件。嘿嘿。
讲到这⾥也结束了,我⾃⼰⽬前在使⽤第三种⽅法,虽然官⽅推荐第⼀种,我觉得⽤着⽐较⿇烦唉。~
总结
以上就是这篇⽂章的全部内容了,希望本⽂的内容对⼤家的学习或者⼯作具有⼀定的参考学习价值,如果有疑问⼤家可以留⾔交流,谢谢⼤家对的⽀持。