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 相关文章推荐
解决FireFox下[使用event很麻烦]的问题
Nov 26 Javascript
JavaScript Archive Network 集合
May 12 Javascript
“不能执行已释放的Script代码”错误的原因及解决办法
Sep 09 Javascript
jQuery hover 延时器实现代码
Mar 12 Javascript
jQuery中extend()和fn.extend()方法详解
Jun 03 Javascript
微信小程序教程之本地图片上传(leancloud)实例详解
Nov 16 Javascript
Vue.js如何优雅的进行form validation
Apr 07 Javascript
vue之数据交互实例代码
Jun 20 Javascript
使用vue的v-for生成table并给table加上序号的实例代码
Oct 27 Javascript
使用Javascript简单计算器
Nov 17 Javascript
Vue动态修改网页标题的方法及遇到问题
Jun 09 Javascript
jQuery删除/清空指定元素的所有子节点实例代码
Jul 04 jQuery
基于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安装扩展mysqli的实现步骤及报错解决办法
2017/09/23 PHP
通过javascript设置css属性的代码
2009/12/28 Javascript
将HTMLCollection/NodeList/伪数组转换成数组的实现方法
2011/06/20 Javascript
js对象与打印对象分析比较
2013/04/23 Javascript
javascript相等运算符与等同运算符详细介绍
2013/11/09 Javascript
javascript自动给文本url地址增加链接的方法分享
2014/01/20 Javascript
JavaScript极简入门教程(一):基础篇
2014/10/25 Javascript
javascript实现了照片拖拽点击置顶的照片墙代码
2015/04/03 Javascript
JavaScript中的Reflect对象详解(ES6新特性)
2016/07/22 Javascript
javascript简单实现等比例缩小图片的方法
2016/07/27 Javascript
JS对象的深度克隆方法示例
2017/03/16 Javascript
详解如何将angular-ui的图片轮播组件封装成一个指令
2017/05/09 Javascript
20行js代码实现的贪吃蛇小游戏
2017/06/20 Javascript
jQuery中$原理实例分析
2018/08/13 jQuery
layui-laydate时间日历控件使用方法详解
2018/11/15 Javascript
Element Dropdown下拉菜单的使用方法
2020/07/26 Javascript
[48:38]DOTA2亚洲邀请赛 3.31 小组赛 B组 Mineski vs Secret
2018/03/31 DOTA
Python算法输出1-9数组形成的结果为100的所有运算式
2017/11/03 Python
Python3.6安装及引入Requests库的实现方法
2018/01/24 Python
python爬虫项目设置一个中断重连的程序的实现
2019/07/26 Python
Django模型修改及数据迁移实现解析
2019/08/01 Python
python__name__原理及用法详解
2019/11/02 Python
浅析python,PyCharm,Anaconda三者之间的关系
2019/11/27 Python
python 常见的反爬虫策略
2020/09/27 Python
英国和爱尔兰的自炊式豪华度假小屋:Rural Retreats
2018/06/08 全球购物
const char*, char const*, char*const的区别是什么
2014/07/09 面试题
财经学院自荐信范文
2014/02/02 职场文书
中学生期末评语
2014/02/03 职场文书
2013年军训通讯稿
2014/02/05 职场文书
中学生个人自我评价
2014/02/06 职场文书
大学本科生职业生涯规划书范文
2014/09/14 职场文书
党员检讨书
2014/10/13 职场文书
工伤事故赔偿协议书
2014/10/27 职场文书
OpenCV实现常见的四种图像几何变换
2022/04/01 Python
TV动画《史上最强大魔王转生为村民A》番宣CM公布
2022/04/01 日漫
Python中的 No Module named ***问题及解决
2022/07/23 Python