問題
當我們使用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組件。
我目前也沒有更好的辦法了
