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选择器如何获取父级元素、同级元素、子元素
May 14 Javascript
AngularJS directive返回对象属性详解
Mar 28 Javascript
Bootstrap开发实战之第一次接触Bootstrap
Jun 02 Javascript
Vue.js系列之项目结构说明(2)
Jan 03 Javascript
JavaScript优化以及前段开发小技巧
Feb 02 Javascript
JS实现微信里判断页面是否被分享成功的方法
Jun 06 Javascript
使用微信小程序开发弹出框应用实例详解
Oct 18 Javascript
Vue传参一箩筐(页面、组件)
Apr 04 Javascript
Vue+Element实现动态生成新表单并添加验证功能
May 23 Javascript
基于 vue-skeleton-webpack-plugin 的骨架屏实战
Aug 05 Javascript
基于vue+echarts 数据可视化大屏展示的方法示例
Mar 09 Javascript
原生js实现滑块区间组件
Jan 20 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 var_dump()函数的详解
2013/06/05 PHP
利用PHP内置SERVER开启web服务(本地开发使用)
2021/03/09 PHP
javascript编程起步(第二课)
2007/01/10 Javascript
基于jQuery的星级评分插件
2011/08/12 Javascript
js去字符串前后空格5种实现方法及比较
2013/04/03 Javascript
JS 精确统计网站访问量的实例代码
2013/07/05 Javascript
Visual Studio中js调试的方法图解
2014/06/30 Javascript
jquery中each遍历对象和数组示例
2014/08/05 Javascript
AngularJS ngModel实现指令与输入直接的数据通信
2016/09/21 Javascript
Angular学习笔记之angular的$filter服务浅析
2016/11/12 Javascript
React Native之ListView实现九宫格效果的示例
2017/08/02 Javascript
微信小程序实现tab左右切换效果
2020/11/15 Javascript
基于vue-cli npm run build之后vendor.js文件过大的解决方法
2018/09/27 Javascript
vue项目创建并引入饿了么elementUI组件的步骤
2019/04/11 Javascript
vue 解决mintui弹窗弹起来,底部页面滚动bug问题
2020/11/12 Javascript
js闭包的9个使用场景
2020/12/29 Javascript
[02:57]DOTA2亚洲邀请赛小组赛第四日 赛事回顾
2015/02/02 DOTA
Python创建模块及模块导入的方法
2015/05/27 Python
Pthon批量处理将pdb文件生成dssp文件
2015/06/21 Python
Python安装第三方库的3种方法
2015/06/21 Python
python实现汉诺塔递归算法经典案例
2021/03/01 Python
python爬取NUS-WIDE数据库图片
2016/10/05 Python
python 编程之twisted详解及简单实例
2017/01/28 Python
python使用opencv读取图片的实例
2017/08/17 Python
PYTHON绘制雷达图代码实例
2019/10/15 Python
Python3+PyCharm+Django+Django REST framework配置与简单开发教程
2021/02/16 Python
斯图尔特·韦茨曼鞋加拿大官网:Stuart Weitzman加拿大
2019/10/13 全球购物
波兰在线杂货店:Polski Koszyk
2019/11/02 全球购物
致铅球运动员加油稿
2014/02/13 职场文书
新农村建设标语
2014/06/24 职场文书
2014村书记党建工作汇报材料
2014/11/02 职场文书
公司清洁工岗位职责
2015/04/15 职场文书
邓小平文选读书笔记
2015/06/29 职场文书
经典人生语录分享:不畏将来,不念过去,笑对当下
2019/12/12 职场文书
Linux系统下安装PHP7.3版本
2021/06/26 PHP
vue @ ~ 相对路径 路径别名设置方式
2022/06/05 Vue.js