欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

react-router v4如何使用history控制路由跳转详解

程序员文章站 2022-05-08 18:41:20
前言 距离react router v4 正式发布也已经挺久了,这周把一个react的架子做了升级,之前的路由用的还是v2.7.0版的,所以决定把路由也升级下,正好“尝尝...

前言

距离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组件。嘿嘿。

讲到这里也结束了,我自己目前在使用第三种方法,虽然官方推荐第一种,我觉得用着比较麻烦唉。~

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。