如何在react-router v4上获取历史记录?

时间:2017-03-08 13:37:26

标签: reactjs react-router

我有一些小问题从React-Router v3迁移到v4。 在v3中,我能够在任何地方执行此操作:

import { browserHistory } from 'react-router';
browserHistory.push('/some/path');

我如何在第4版中实现这一目标。

我知道当你在Component中时,我可以使用,特别是withRouter,反应上下文或事件路由器道具。但事实并非如此。

我正在寻找v4中NavigatingOutsideOfComponents的等价性

7 个答案:

答案 0 :(得分:129)

您只需要一个导出history对象的模块。然后,您将在整个项目中导入该对象。

// history.js
import { createBrowserHistory } from 'history'

export default createBrowserHistory({
  /* pass a configuration object here if needed */
})

然后,您将使用<Router>组件而不是使用其中一个内置路由器。

// index.js
import { Router } from 'react-router-dom'
import history from './history'
import App from './App'

ReactDOM.render((
  <Router history={history}>
    <App />
  </Router>
), holder)
// some-other-file.js
import history from './history'
history.push('/go-here')

答案 1 :(得分:58)

这个有效! https://reacttraining.com/react-router/web/api/withRouter

import { withRouter } from 'react-router-dom';

class MyComponent extends React.Component {
  render () {
    this.props.history;
  }
}

withRouter(MyComponent);

答案 2 :(得分:7)

模拟接受回答您可以做的是使用reactreact-router本身为您提供history对象,您可以将其放在文件中然后导出。

<强> history.js

import React from 'react';
import { withRouter } from 'react-router';

// variable which will point to react-router history
let globalHistory = null;

// component which we will mount on top of the app
class Spy extends React.Component {
  componentWillMount() {
    const { history } = this.props;
    globalHistory = history; 
  }

  componentWillReceiveProps(nextProps) {
    globalHistory = nextProps.history;
  }

  render(){
    return null;
  }
}

export const GlobalHistory = withRouter(Spy);

// export react-router history
export default function getHistory() {    
  return globalHistory;
}

稍后您导入Component并mount以初始化历史变量:

import { BrowserRouter } from 'react-router-dom';
import { GlobalHistory } from './history';

function render() {
  ReactDOM.render(
    <BrowserRouter>
        <div>
            <GlobalHistory />
            //.....
        </div>
    </BrowserRouter>
    document.getElementById('app'),
  );
}

然后你可以在你的应用程序安装时导入它:

import getHistory from './history'; 

export const goToPage = () => (dispatch) => {
  dispatch({ type: GO_TO_SUCCESS_PAGE });
  getHistory().push('/success'); // at this point component probably has been mounted and we can safely get `history`
};

我甚至做过npm package就是这样做的。

答案 3 :(得分:6)

如果仅需要历史对象以导航到其他组件,则基于this answer

import { useHistory } from "react-router-dom";

function HomeButton() {
  const history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}

答案 4 :(得分:4)

如果您使用的是redux和redux-thunk,那么最好的解决方案就是使用react-router-redux

// then, in redux actions for example
import { push } from 'react-router-redux'

dispatch(push('/some/path'))
  

查看文档进行一些配置非常重要。

答案 5 :(得分:0)

在App.js中

 import {useHistory } from "react-router-dom";

 const TheContext = React.createContext(null);

 const App = () => {
   const history = useHistory();

   <TheContext.Provider value={{ history, user }}>

    <Switch>
        <Route exact path="/" render={(props) => <Home {...props} />} />
        <Route
          exact
          path="/sign-up"
          render={(props) => <SignUp {...props} setUser={setUser} />}
        /> ...

然后添加一个子组件:

const Welcome = () => {
    
    const {user, history} = React.useContext(TheContext); 
    ....

答案 6 :(得分:-1)

react-router的特定情况下,使用context是一种有效的案例,例如

class MyComponent extends React.Component {
  props: PropsType;

  static contextTypes = {
    router: PropTypes.object
  };

  render () {
    this.context.router;
  }
}

您可以通过路由器上下文访问历史记录的实例,例如this.context.router.history