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 相关文章推荐
数组Array进行原型prototype扩展后带来的for in遍历问题
Feb 07 Javascript
jquery限制输入字数,并提示剩余字数实现代码
Dec 24 Javascript
js实现上传图片预览的方法
Feb 09 Javascript
jQuery基于ajax实现星星评论代码
Aug 07 Javascript
jQuery代码实现表格中点击相应行变色功能
May 09 Javascript
js实现按钮控制带有停顿效果的图片滚动
Aug 30 Javascript
JavaScript中最常见的三个面试题解析
Mar 04 Javascript
原生JS改变透明度实现轮播效果
Mar 24 Javascript
Angular浏览器插件Batarang介绍及使用
Feb 07 Javascript
vue中axios的封装问题(简易版拦截,get,post)
Jun 15 Javascript
详解Vue取消eslint语法限制
Aug 04 Javascript
Vue-axios-post数据后端接不到问题解决
Jan 09 Javascript
基于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
php删除字符串末尾子字符,删除开始字符,删除两端字符(实现代码)
2013/06/27 PHP
PHP连接局域网MYSQL数据库的简单实例
2013/08/26 PHP
php计算年龄精准到年月日
2015/11/17 PHP
屏蔽PHP默认设置中的Notice警告的方法
2016/05/20 PHP
Netbeans 8.2与PHP相关的新特性介绍
2016/10/08 PHP
php7安装yar扩展的方法详解
2017/08/03 PHP
PHP实现将多个文件压缩成zip格式并下载到本地的方法示例
2018/05/23 PHP
Jquery 学习笔记(一)
2009/10/13 Javascript
jQuery对指定元素中指定字符串进行替换的方法
2015/03/17 Javascript
JavaScript函数节流概念与用法实例详解
2016/06/20 Javascript
vue系列之动态路由详解【原创】
2017/09/10 Javascript
自定义vue组件发布到npm的方法
2018/05/09 Javascript
vue 解决addRoutes动态添加路由后刷新失效问题
2018/07/02 Javascript
详解操作虚拟dom模拟react视图渲染
2018/07/25 Javascript
jQuery 获取除某指定对象外的其他对象 ( :not() 与.not())
2018/10/10 jQuery
使用 vue 实现灭霸打响指英雄消失的效果附demo
2019/05/06 Javascript
JS实现简单的文字无缝上下滚动功能示例
2019/06/22 Javascript
javascript二维数组和对象的深拷贝与浅拷贝实例分析
2019/10/26 Javascript
[01:30]2016国际邀请赛中国区预选赛神秘商店火爆开启
2016/06/26 DOTA
python赋值操作方法分享
2013/03/23 Python
Python中使用logging模块代替print(logging简明指南)
2014/07/09 Python
Python socket网络编程TCP/IP服务器与客户端通信
2017/01/05 Python
Python中max函数用于二维列表的实例
2018/04/03 Python
基于Python 装饰器装饰类中的方法实例
2018/04/21 Python
解决python "No module named pip" 的问题
2018/10/13 Python
Python3实现的反转单链表算法示例
2019/03/08 Python
用python写测试数据文件过程解析
2019/09/25 Python
银行毕业实习自我鉴定
2013/09/19 职场文书
高中生毕业自我鉴定范文
2013/12/22 职场文书
农业资源与环境专业自荐信范文
2013/12/30 职场文书
《白鹅》教学反思
2014/04/13 职场文书
留学顾问岗位职责
2014/04/14 职场文书
质量负责人任命书
2014/06/06 职场文书
2014党委书记四风问题对照检查材料思想汇报
2014/09/22 职场文书
2014年骨干教师工作总结
2014/12/19 职场文书
Feign调用全局异常处理解决方案
2021/06/24 Java/Android