react-router v4 使用 history 控制路由跳转

原文地址: https://github.com/brickspert... (若是你以为对你有帮助,能够去github上点个star哦。)javascript

github上会更新,这里不更新java

问题

当咱们使用react-router v3的时候,咱们想跳转路径,咱们通常这样处理react

  1. 咱们从react-router导出browserHistoryios

  2. 咱们使用browserHistory.push()等等方法操做路由跳转。git

相似下面这样github

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等的导出~~redux

那怎么办?我如何控制路由跳转呢???axios

解决方法

1. 使用 withRouter

withRouter高阶组件,提供了history让你使用~react-router

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传递过去。。dom

就像问题章节的代码那种场景使用,咱们就必须从组件中传一个history参数过去。。。

2. 使用 Context

react-router v4Router 组件中经过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。看代码~

  1. 咱们本身建立一个history

// src/history.js

import createHistory from 'history/createBrowserHistory';

export default createHistory();
  1. 咱们使用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'),
);
  1. 其余地方咱们就能够这样用了

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

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

相关文章
相关标签/搜索