react-router v4如何使用history控制路由跳转详解


Posted in Javascript onJanuary 09, 2018

前言

距离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() {
 this.context.router.history.push("/some/Path");
 }
 ...
}

当然,这种方法慎用~尽量不用。因为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';
import history from './history';
ReactDOM.render(
 <Provider store={store}>
 <Router history={history}>
  ...
 </Router>
 </Provider>,
 document.getElementById('root'),
);

其他地方我们就可以这样用了

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组件。嘿嘿。

讲到这里也结束了,我自己目前在使用第三种方法,虽然官方推荐第一种,我觉得用着比较麻烦唉。~

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jquery上传插件fineuploader上传文件使用方法(jquery图片上传插件)
Dec 05 Javascript
js函数模拟显示桌面.scf程序示例
Apr 20 Javascript
jQuery实现Div拖动+键盘控制综合效果的方法
Mar 10 Javascript
JavaScript判断是否为数字的4种方法及效率比较
Apr 01 Javascript
关于JavaScript作用域你想知道的一切
Feb 04 Javascript
使用命令行工具npm新创建一个vue项目的方法
Dec 27 Javascript
JS设计模式之观察者模式实现实时改变页面中金额数的方法
Feb 05 Javascript
仿vue-cli搭建属于自己的脚手架的方法步骤
Apr 17 Javascript
在node环境下parse Smarty模板的使用示例代码
Nov 15 Javascript
js中关于Blob对象的介绍与使用
Nov 29 Javascript
node.js开发辅助工具nodemon安装与配置详解
Feb 06 Javascript
Vue2项目中对百度地图的封装使用详解
Jun 16 Vue.js
基于vue-ssr服务端渲染入门详解
Jan 08 #Javascript
浅谈Vue2.0父子组件间事件派发机制
Jan 08 #Javascript
如何快速解决JS或Jquery ajax异步跨域的问题
Jan 08 #jQuery
jQuery+SpringMVC中的复选框选择与传值实例
Jan 08 #jQuery
浅谈SpringMVC中post checkbox 多选框value的值(隐藏域方式)
Jan 08 #Javascript
JQuery实现table中tr上移下移的示例(超简单)
Jan 08 #jQuery
使用 Vue 绑定单个或多个 Class 名的实例代码
Jan 08 #Javascript
You might like
使用ThinkPHP的自动完成实现无限级分类实例详解
2016/09/02 PHP
PHP通过引用传递参数用法分析
2016/12/01 PHP
jQuery之$(document).ready()使用介绍
2012/04/05 Javascript
JavaScript中getUTCSeconds()方法的使用详解
2015/06/11 Javascript
jQuery绑定事件的几种实现方式
2016/05/09 Javascript
JSONP跨域请求实例详解
2016/07/04 Javascript
BootStrap学习系列之Bootstrap Typeahead 组件实现百度下拉效果(续)
2016/07/07 Javascript
js 获取范围内的随机数实例代码
2016/08/02 Javascript
Angularjs的Controller间通信机制实例分析
2016/11/07 Javascript
微信小程序 picker-view 组件详解及简单实例
2017/01/10 Javascript
原生JavaScript实现AJAX、JSONP
2017/02/07 Javascript
基于JavaScript实现下拉列表左右移动代码
2017/02/07 Javascript
js canvas实现QQ拨打电话特效
2017/05/10 Javascript
详解从angular-cli:1.0.0-beta.28.3升级到@angular/cli:1.0.0
2017/05/22 Javascript
jquery3和layui冲突导致使用layui.layer.full弹出全屏iframe窗口时高度152px问题
2019/05/12 jQuery
Vue项目实现换肤功能的一种方案分析
2019/08/28 Javascript
vue使用原生swiper代码实例
2020/02/05 Javascript
ES2020系列之空值合并运算符 '??'
2020/07/22 Javascript
python实现给数组按片赋值的方法
2015/07/28 Python
Python 字典与字符串的互转实例
2017/01/13 Python
python smtplib发送带附件邮件小程序
2018/05/22 Python
python学生管理系统
2019/01/30 Python
Python常用的json标准库
2019/02/19 Python
用Python+OpenCV对比图像质量的几种方法
2019/07/15 Python
django+tornado实现实时查看远程日志的方法
2019/08/12 Python
python中字典按键或键值排序的实现代码
2019/08/27 Python
Python使用百度api做人脸对比的方法
2019/08/28 Python
python 密码学示例——理解哈希(Hash)算法
2020/09/21 Python
Python大批量搜索引擎图像爬虫工具详解
2020/11/16 Python
小学生中国梦演讲稿
2014/04/23 职场文书
2014幼儿园班主任工作总结
2014/12/04 职场文书
雾霾停课通知
2015/04/24 职场文书
六一儿童节园长致辞
2015/07/31 职场文书
申请吧主发表的感言
2015/08/03 职场文书
Nginx 反向代理解决跨域问题多种情况分析
2022/01/18 Servers
Linux中一对多配置日志服务器的详细步骤
2022/07/23 Servers