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

講到這裏也結束了,我本身目前在使用第三種方法,雖然官方推薦第一種,我以爲用着比較麻煩唉。~

相關文章
相關標籤/搜索