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


問題

當我們使用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'); //這里
      });
}

 

問題來了,在react-router v4中,不提供browserHistory等的導出~~

那怎么辦?我如何控制路由跳轉呢???

解決方法

  • 使用 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參數過去。。。

  • 使用 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哦。在未來版本中有可能被拋棄哦。

  • 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(); 

 

新的版本需要這樣引入

import { createHashHistory,createBrowserHistory } from 'history'; // 是hash路由 history路由 自己根據需求來定

  

ts引入

import * as createHistory from "history";
export default createHistory.createBrowserHistory();

  

 

 

 我們使用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'); //這里
      });
}

 

this.props.history.push("/two")

  

react-router v4推薦使用BrowserRouter組件,而在第三個解決方案中,我們拋棄了這個組件,又回退使用了Router組件。

我目前也沒有更好的辦法了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM