Wie bekomme ich den Verlauf auf React-Router v4?

100

Ich habe ein kleines Problem bei der Migration von React-Router v3 auf v4. in v3 konnte ich das überall machen:

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

Wie erreiche ich das in v4?

Ich weiß, dass ich die Hoc- withRouter, Reaktionskontext- oder Event-Router-Requisiten verwenden kann, wenn Sie sich in einer Komponente befinden. aber das ist bei mir nicht der Fall.

Ich suche nach der Äquivalenz von NavigatingOutsideOfComponents in v4

Storm_Buster
quelle
1
Danke @Chris, aber wie gesagt, ich bin nicht in Component.
Storm_Buster
@ Chris in einer Utility-Klasse, überprüfen Sie bitte github.com/ReactTraining/react-router/blob/master/docs/guides/… , es könnte ein Redux Middlewarere oder irgendetwas anderes gewesen sein
Storm_Buster
einfachster Weg stackoverflow.com/a/53916596/3966458
Saahithyan Vigneswaran
Am Ende habe ich den BrowserRouter als Root-Komponente verwendet. Auf diese Weise könnte ich die App-Komponente mit Router verwenden. Nicht genau das, wonach Sie gefragt haben, aber ich habe die gleichen Anforderungen und das reicht mir.
Der Narr

Antworten:

179

Sie benötigen lediglich ein Modul, das ein historyObjekt exportiert . Dann würden Sie dieses Objekt in Ihr Projekt importieren.

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

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

Anstatt einen der integrierten Router zu verwenden, würden Sie dann die <Router>Komponente verwenden.

// 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')
Paul S.
quelle
1
Vielen Dank! Im Moment musste ich mit react-router4 stattdessen diesen Import in history.js verwenden: import createBrowserHistory from 'history / createBrowserHistory';
Peter.bartos
3
Es hat für mich funktioniert, wenn ich history = {history} in Route eingefügt habe und wie ein Requisit
vorbeigekommen
1
Wir können withHistory verwenden und den Verlauf in Requisiten abrufen, anstatt eine separate Datei zu erstellen. Diese Lösung hat bei mir mit Redux nicht funktioniert.
Zeel Shah
4
Importieren, createHashHistorywenn Sie verwendet haben HashRouter.
David Harkness
1
@ HassanAzzam Sie verwenden wahrscheinlich den React-Router V5, und diese Antwort funktioniert für V4, nicht für V5. Ich habe im Moment die gleiche Herausforderung und suche überall, kann es aber nicht zum Laufen bringen. history.push außerhalb der Komponente funktioniert, aber Klicks auf den Link funktionieren nicht mehr.
Waterlink
71

Das funktioniert! 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);
Justin Yueh
quelle
26
solange Sie sich in einer Komponente befinden. Ich bin nicht in einer Komponente
Storm_Buster
1
Vielen Dank, dies ist der einfachste und einfachste Weg, um von einer Komponente aus eine Verbindung zu einer anderen Route herzustellen. Ich möchte nur hinzufügen, dass Sie tun this.props.history.push('/some_route');müssen, damit es funktioniert.
Dannytenaglias
1
@storm_buster const Component = props => {... // stuff}und export default withRouter(Component)arbeitet für mich an einer zustandslosen Komponente
Karl Taylor
10

Similiary zu akzeptierte Antwort , was Sie tun können , Gebrauch ist reactund react-routersich um Ihnen historyObjekt , das Sie Rahmen in einer Datei kann und dann den Export.

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;
}

Sie importieren später die Komponente und hängen sie ein, um die Verlaufsvariable zu initialisieren:

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

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

Und dann können Sie einfach in Ihre App importieren, wenn sie gemountet wurde:

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`
};

Ich habe sogar ein npm-Paket gemacht , das genau das tut.

Tomasz Mularczyk
quelle
Ab Reaktion 16.9 gibt diese Lösung eine Verfallswarnung für componentWillMount und componentWillReceiveProps aus.
ian
1
@ian wahr, behoben, dass
Tomasz Mularczyk
5

Wenn Sie Redux und Redux-Thunk verwenden, ist die beste Lösung die Verwendung von React-Router-Redux

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

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

Es ist wichtig, die Dokumente zu sehen, um einige Konfigurationen durchzuführen.

Arnold Gandarillas
quelle
1
Ich kam hierher in der Hoffnung, genau diese Lösung zu finden, danke
vapurrmaid
4

Basierend auf dieser Antwort, wenn Sie nur ein Verlaufsobjekt benötigen, um zu einer anderen Komponente zu navigieren:

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>
  );
}
Konrad Grzyb
quelle
FALSCH, Sie befinden sich innerhalb einer Komponente. siehe // some-other-file.js aus der akzeptierten Antwort
Storm_Buster
0

In 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} />}
        /> ...

Dann in einer untergeordneten Komponente:

const Welcome = () => {
    
    const {user, history} = React.useContext(TheContext); 
    ....
Eichhörnchen
quelle
-2

Im speziellen Fall von react-routerist die Verwendung contextein gültiges Fallszenario, z

class MyComponent extends React.Component {
  props: PropsType;

  static contextTypes = {
    router: PropTypes.object
  };

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

Sie können über den Routerkontext auf eine Instanz des Verlaufs zugreifen, z this.context.router.history.

Gajus
quelle
Die Frage bezieht sich speziell darauf, wann Sie sich außerhalb einer Komponente befinden, sodass this.context nicht als Option verfügbar ist:> "Ich weiß, dass ich die Requisiten für Hoc withRouter, React Context oder Event Router verwenden kann, wenn Sie sich in einer Komponente befinden. Aber das ist bei mir nicht der Fall. "
SunshinyDoyle