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 相关文章推荐
在模板页面的js使用办法
Apr 01 Javascript
JavaScript版TAB选项卡效果实例
Aug 16 Javascript
IE浏览器不支持getElementsByClassName的解决方法
Aug 27 Javascript
jQuery经过一段时间自动隐藏指定元素的方法
Mar 17 Javascript
jQuery soColorPacker 网页拾色器
Jun 22 Javascript
jQuery简单倒计时效果完整示例
Sep 20 Javascript
原生JS实现跑马灯效果
Feb 20 Javascript
基于JavaScript实现的顺序查找算法示例
Apr 14 Javascript
通俗解释JavaScript正则表达式快速记忆
Aug 23 Javascript
使用socket.io实现简单聊天室案例
Jan 02 Javascript
在vue项目中,将juery设置为全局变量的方法
Sep 25 Javascript
Node.js Event Loop各阶段讲解
Mar 08 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
使用sockets:从新闻组中获取文章(三)
2006/10/09 PHP
PHP 和 XML: 使用expat函数(三)
2006/10/09 PHP
php中HTTP_REFERER函数用法实例
2014/11/21 PHP
smarty模板引擎中变量及变量修饰器用法实例
2015/01/22 PHP
PHP文件上传操作实例详解
2016/09/27 PHP
php实现微信发红包功能
2018/07/13 PHP
深入研究PHP中的preg_replace和代码执行
2018/08/15 PHP
PDO::exec讲解
2019/01/28 PHP
一段利用WSH获取登录时间的jscript代码
2008/05/11 Javascript
js中将字符串转换成json的三种方式
2011/01/12 Javascript
Javascript的各种节点操作实例演示代码
2012/06/27 Javascript
Javascript执行效率全面总结
2013/11/04 Javascript
Chrome扩展页面动态绑定JS事件提示错误
2014/02/11 Javascript
JQuery性能优化的几点建议
2014/05/14 Javascript
jQuery插件学习教程之SlidesJs轮播+Validation验证
2016/07/12 Javascript
HTML5+jQuery实现搜索智能匹配功能
2017/03/24 jQuery
react-native之ART绘图方法详解
2017/08/08 Javascript
使用Node.js实现ORM的一种思路详解(图文)
2017/10/24 Javascript
详解Vue 如何监听Array的变化
2019/06/06 Javascript
5分钟教你用nodeJS手写一个mock数据服务器的方法
2019/09/10 NodeJs
详解vue 自定义组件使用v-model 及探究其中原理
2019/10/11 Javascript
详解ES6数组方法find()、findIndex()的总结
2020/05/12 Javascript
python将人民币转换大写的脚本代码
2013/02/10 Python
python操作数据库之sqlite3打开数据库、删除、修改示例
2014/03/13 Python
Python实现的简单发送邮件脚本分享
2014/11/07 Python
python中文分词教程之前向最大正向匹配算法详解
2017/11/02 Python
python中的turtle库函数简单使用教程
2018/07/23 Python
基于多进程中APScheduler重复运行的解决方法
2019/07/22 Python
pytorch读取图像数据转成opencv格式实例
2020/06/02 Python
浅析Python的命名空间与作用域
2020/11/25 Python
英国Radley包德国官网:Radley London德国
2019/11/18 全球购物
印刷工程专业应届生求职信
2013/09/29 职场文书
学生会竞聘书范文
2014/03/31 职场文书
长城英文导游词
2015/01/30 职场文书
公司奖励通知
2015/04/21 职场文书
JavaScript原型链详解
2021/11/07 Javascript