【问题标题】:How to get history on react-router v4?如何获取 react-router v4 的历史记录?
【发布时间】:2017-07-29 02:38:22
【问题描述】:

我在从 React-Router v3 迁移到 v4 时遇到了一些小问题。 在 v3 中,我可以在任何地方执行此操作:

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

如何在 v4 中实现这一点。

我知道当您在组件中时我可以使用 hoc withRouter、反应上下文或事件路由器道具。但对我来说不是这样。

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

【问题讨论】:

标签: reactjs react-router


【解决方案1】:

您只需要一个导出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')

【讨论】:

  • 非常感谢!目前,使用 react-router4,我不得不在 history.js 中使用这个导入: import createBrowserHistory from 'history/createBrowserHistory';
  • 当我将 history={history} 放入 Route 并像道具一样传递时,它对我有用
  • 我们可以使用 withHistory 并在 props 中获取历史记录,而不是创建单独的文件。这个解决方案不适用于 redux。
  • 如果您使用的是HashRouter,请导入createHashHistory
  • @HassanAzzam 您可能正在使用 react-router V5,这个答案适用于 V4,而不是 V5。我现在面临同样的挑战,并且正在到处寻找,但无法使其发挥作用。 history.push 在组件之外有效,但不再点击链接。
【解决方案2】:

react-router的具体情况下,使用context是一个有效的case场景,例如

class MyComponent extends React.Component {
  props: PropsType;

  static contextTypes = {
    router: PropTypes.object
  };

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

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

【讨论】:

  • 这个问题具体是询问何时在组件之外,因此 this.context 不能作为选项使用:>“我知道我可以使用 hoc withRouter、react context 或事件路由器道具当你在一个组件中时。但对我来说不是这样。"
【解决方案3】:

这行得通! 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);

【讨论】:

  • 只要你在一个组件中。我不在组件中
  • 谢谢,这是从组件链接到另一条路由的最简单、最直接的方法。我只想补充一点,您需要执行 this.props.history.push('/some_route'); 才能使其正常工作。
  • @storm_buster const Component = props =&gt; {... // stuff}export default withRouter(Component) 在无状态组件上为我工作
【解决方案4】:

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

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

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

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

【讨论】:

  • 我来到这里希望找到这个确切的解决方案,谢谢
【解决方案5】:

与接受的答案类似,您可以使用 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 {
  constructor(props) {
    super(props)
    globalHistory = props.history; 
  }

  componentDidUpdate() {
    globalHistory = this.props.history;
  }

  render(){
    return null;
  }
}

export const GlobalHistory = withRouter(Spy);

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

您稍后再导入组件并挂载以初始化历史变量:

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 就是这样做的。

【讨论】:

  • 从 reactjs 16.9 开始,此解决方案将在 componentWillMount 和 componentWillReceiveProps 上发出弃用警告。
  • @ian true,已修复
【解决方案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>
  );
}

【讨论】:

  • 错了,你在一个组件中。从接受的答案中查看 // some-other-file.js
  • useHistory(和 React Hooks)比公认的答案更好/更干净
【解决方案7】:

在 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); 
    ....

【讨论】:

    猜你喜欢
    • 2017-12-08
    • 1970-01-01
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多