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 arguments.callee的应用代码
May 07 Javascript
EASYUI TREEGRID异步加载数据实现方法
Aug 22 Javascript
jquery动画2.元素坐标动画效果(创建一个图片走廊)
Aug 24 Javascript
用js写了一个类似php的print_r输出换行功能
Feb 18 Javascript
JS操作图片(增,删,改) 例子
Apr 17 Javascript
Javascript中查找不以XX字符结尾的单词示例代码
Oct 15 Javascript
实例讲解JavaScript的Backbone.js框架中的View视图
May 05 Javascript
JavaScript中的return布尔值的用法和原理解析
Aug 14 Javascript
Three.js中网格对象MESH的属性与方法详解
Sep 27 Javascript
Vue.js更改调试地址端口号的实例
Sep 19 Javascript
详解vue 组件
Jun 11 Javascript
一篇文章让你搞懂JavaScript 原型和原型链
Nov 23 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
使用zend studio for eclipse不能激活代码提示功能的解决办法
2009/10/11 PHP
memcached 和 mysql 主从环境下php开发代码详解
2010/05/16 PHP
php 文本文件的读取效率
2012/02/10 PHP
eaglephp使用微信api接口开发微信框架
2014/01/09 PHP
php结合js实现点击超链接执行删除确认操作
2014/10/31 PHP
php检测图片主要颜色的方法
2015/07/01 PHP
Yii框架模拟组件调用注入示例
2019/11/11 PHP
PHP中类与对象功能、用法实例解读
2020/03/27 PHP
基于JQuery框架的AJAX实例代码
2009/11/03 Javascript
理解Javascript的call、apply
2015/12/16 Javascript
JQuery的常用选择器、过滤器、方法全面介绍
2016/05/25 Javascript
JS 终止执行的实现方法
2016/11/24 Javascript
JS中Array数组学习总结
2017/01/18 Javascript
十大热门的JavaScript框架和库
2017/03/21 Javascript
axios基本入门用法教程
2017/03/25 Javascript
使用angular帮你实现拖拽的示例
2017/07/05 Javascript
vue-cli的build的文件夹下没有dev-server.js文件配置mock数据的方法
2019/04/17 Javascript
js 获取扫码枪输入数据的方法
2020/06/10 Javascript
python三元运算符实现方法
2013/12/17 Python
深度剖析使用python抓取网页正文的源码
2014/06/11 Python
跟老齐学Python之关于类的初步认识
2014/10/11 Python
python多个模块py文件的数据共享实例
2019/01/11 Python
在keras 中获取张量 tensor 的维度大小实例
2020/06/10 Python
基于python实现计算两组数据P值
2020/07/10 Python
法国面料和小百货在线商店:Mondial Tissus
2019/03/23 全球购物
护理专业自荐信范文
2014/02/26 职场文书
经贸专业毕业生求职信范文
2014/05/01 职场文书
四风问题个人自查剖析材料思想汇报
2014/09/21 职场文书
乡镇党员干部群众路线对照检查材料思想汇报
2014/09/28 职场文书
公司仓管员岗位职责
2015/04/01 职场文书
法定代表人身份证明书
2015/06/18 职场文书
《只有一个地球》教学反思
2016/02/16 职场文书
Python代码,能玩30多款童年游戏!这些有几个是你玩过的
2021/04/27 Python
Python机器学习之PCA降维算法详解
2021/05/19 Python
继承Win10缺点!教你关闭Win11烦人的网络搜索
2021/11/23 数码科技
实战 快速定位MySQL的慢SQL
2022/03/22 MySQL