React-Router (v4) Wie gehe ich zurück?

84

Ich versuche herauszufinden, wie ich zur vorherigen Seite zurückkehren kann. ich benutze[react-router-v4][1]

Dies ist der Code, den ich auf meiner ersten Zielseite konfiguriert habe:

<Router>
  <div>
    <Link to="/"><div className="routerStyle"><Glyphicon glyph="home" /></div></Link>
    <Route exact path="/" component={Page1}/>
    <Route path="/Page2" component={Page2}/>
    <Route path="/Page3" component={Page3}/>
  </div>
</Router>

Um zu den folgenden Seiten weiterzuleiten, mache ich einfach:

this.props.history.push('/Page2');

Wie kann ich jedoch zur vorherigen Seite zurückkehren? Versuchte einige Dinge wie unten erwähnt, aber kein Glück: 1.this.props.history.goBack();

Gibt Fehler:

TypeError: null ist kein Objekt (Auswertung von 'this.props')

  1. this.context.router.goBack();

Gibt Fehler:

TypeError: null ist kein Objekt (Auswertung von 'this.context')

  1. this.props.history.push('/');

Gibt Fehler:

TypeError: null ist kein Objekt (Auswertung von 'this.props')

Den Page1Code hier unten posten :

import React, {Component} from 'react';
import {Button} from 'react-bootstrap';

class Page1 extends Component {
  constructor(props) {
    super(props);
    this.handleNext = this.handleNext.bind(this);
  }


  handleNext() {
    this.props.history.push('/page2');
  }

  handleBack() {
    this.props.history.push('/');
  }


  /*
   * Main render method of this class
   */
  render() {
    return (
      <div>
        {/* some component code */}


        <div className="navigationButtonsLeft">
          <Button onClick={this.handleBack} bsStyle="success">&lt; Back</Button>
        </div>
        <div className="navigationButtonsRight">
          <Button onClick={this.handleNext} bsStyle="success">Next &gt;</Button>
        </div>

      </div>
    );
  }


export default Page1;
Akshay Lokur
quelle
Was sind die wenigen Dinge, die Sie versucht haben?
Vivek Doshi
3
versuchen Sie es mit this.props.history.goBack(); github.com/ReactTraining/react-router/blob/…
baskax
@ VivekDoshi: Hinzugefügt, was ich zusammen mit Fehlern versucht habe, die ich angetroffen habe
Akshay Lokur
@AkshayLokur, veröffentlichen Sie bitte den vollständigen Code, von dem aus Sie versuchen, this.props.history.goBack () auszuführen.
Vivek Doshi
@ VivekDoshi: Fertig, bitte schauen Sie, danke
Akshay Lokur

Antworten:

119

Ich denke, das Problem liegt in der Bindung:

constructor(props){
   super(props);
   this.goBack = this.goBack.bind(this); // i think you are missing this
}

goBack(){
    this.props.history.goBack();
}

.....

<button onClick={this.goBack}>Go Back</button>

Wie ich angenommen habe, bevor Sie den Code gepostet haben:

constructor(props) {
    super(props);
    this.handleNext = this.handleNext.bind(this);
    this.handleBack = this.handleBack.bind(this); // you are missing this line
}
Vivek Doshi
quelle
funktioniert nicht, wenn die Zurück-Taste des Browsers gedrückt wird und in componentDidUpdateund window.onpopstate?
jmunsch
25
this.props.history.goBack();

Dies ist die richtige Lösung für React-Router v4

Aber eine Sache, die Sie beachten sollten, ist, dass Sie sicherstellen müssen, dass this.props.history existiert.

Das heißt, Sie müssen diese Funktion this.props.history.goBack();innerhalb der Komponente aufrufen , die von <Route /> umschlossen wird

Wenn Sie diese Funktion in einer Komponente aufrufen, die sich tiefer im Komponentenbaum befindet, funktioniert sie nicht.

BEARBEITEN:

Wenn Sie ein Verlaufsobjekt in der Komponente haben möchten, die sich tiefer im Komponentenbaum befindet (der nicht von <Route> umschlossen wird), können Sie Folgendes tun:

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

class Demo extends Component {
    ...
    // Inside this you can use this.props.history.goBack();
}

export default withRouter(Demo);
Hoang Trinh
quelle
Wie kann es also funktionieren? Wie kann man von überall in die Geschichte zurückgehen?
Felipe
@Felipe Sie können von überall zurück gehen. Ich meine nur, dass Sie diese Codezeile in die Containerkomponenten einfügen müssen, um das Objekt "history" zu erhalten. Verwenden Sie diese Codezeile nicht aus Präsentationskomponenten, die nicht von Route ( medium.com/@dan_abramov) umschlossen sind / Smart-and-Dumb-Komponenten-7ca2f9a7c7d0 )
Hoang Trinh
@Felipe: Hallo, bitte überprüfe meine bearbeitete Antwort. Ich denke, es beantwortet Ihre Frage.
Hoang Trinh
Vielen Dank für die withRouter-Bearbeitung, die es für mich behoben hat.
Matthew Rideout
17

Zur Verwendung mit React Router v4 und einer Funktionskomponente an einer beliebigen Stelle im Dom-Tree.

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

const GoBack = ({ history }) => <img src="./images/back.png" onClick={() => history.goBack()} alt="Go back" />;

export default withRouter(GoBack);
Frippera
quelle
Dies ist eine gute Lösung, da keine Lebenszyklusmethode verwendet wird. Es ist mir auch klarer, weil es angibt, was durchlaufen wird, in diesem Fall das Verlaufsobjekt.
AC Patrice
Die Version mit den fetten Pfeilen sieht für mich immer viel sauberer aus, danke dafür.
Egdavid
9

Jede Antwort hier enthält Teile der Gesamtlösung. Hier ist die Komplettlösung, mit der ich es in Komponenten eingesetzt habe, die tiefer liegen als dort, wo Route verwendet wurde:

import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'

^ Sie benötigen diese zweite Zeile, um die Funktion zu importieren und die Komponente am Ende der Seite zu exportieren.

render() {
  return (
  ...
    <div onClick={() => this.props.history.goBack()}>GO BACK</div>
  )
}

^ Benötigte die Pfeilfunktion vs einfach onClick = {this.props.history.goBack ()}

export default withRouter(MyPage)

^ Umschließen Sie den Namen Ihrer Komponente mit 'withRouter ()'

vier Augenraven
quelle
5

Können Sie den Code angeben, in dem Sie ihn verwenden this.props.history.push('/Page2');?

Haben Sie die Methode goBack () ausprobiert?

this.props.history.goBack();

Es ist hier aufgelistet https://reacttraining.com/react-router/web/api/history

Mit einem Live-Beispiel hier https://reacttraining.com/react-router/web/example/modal-gallery

Alfredo Re
quelle
Dies gibt mir Fehler, siehe aktualisierte Frage oben
Akshay Lokur
Können Sie den Code auch hinzufügen this.props.history.push('/Page2');? Wenn this.propsdort nicht null ist, sollte es funktionieren.
Alfredo Re
Nichts wirklich, ich nenne dies einfach beim Klicken auf die Schaltfläche Zurück in meiner Komponente
Akshay Lokur
4

Hier ist die sauberste und einfachste Möglichkeit, mit diesem Problem umzugehen, wodurch auch die wahrscheinlichen Fallstricke der this keyword. Verwenden Sie Funktionskomponenten:

import { withRouter } from "react-router-dom"; Wickeln Sie Ihre componentoder besser App.jsmit dem, withRouter() HOCwas macht history, um "App-weit" verfügbar zu sein. Wenn Sie Ihre Komponente einwickeln, haben Sie nur die history available for that specificWahl, welche Komponente Sie haben.

Also hast du:

  1. export default withRouter(App);

  2. In einer Redux-Umgebung export default withRouter( connect(mapStateToProps, { <!-- your action creators -->})(App), );sollten Sie auf historydiese Weise sogar Benutzer von Ihren Aktionserstellern verwenden können.

in Ihrem componenttun Sie Folgendes:

import {useHistory} from react-router-dom;

const history = useHistory(); // do this inside the component

goBack = () => history.goBack();

<btn btn-sm btn-primary onclick={goBack}>Go Back</btn>

export default DemoComponent;

Gottcha useHistorywird nur aus der neuesten Version 5.1 exportiert. react-router-domAktualisieren Sie daher unbedingt das Paket. Sie sollten sich jedoch keine Sorgen machen müssen. über die vielen Haken der this keyword.

Sie können dies auch zu einer wiederverwendbaren Komponente machen, die Sie in Ihrer App verwenden können.


function BackButton({ children }) {
  let history = useHistory()
  return (
    <button type="button" onClick={() => history.goBack()}>
      {children}
    </button>
  )
}```
Cheers.


Lawrence Eagles
quelle
2
Vielen Dank. Aber warum wird meine Komponente nicht neu gerendert, wenn ich einen Browser zurücksetze?
Stephane
0

Versuchen:

this.props.router.goBack()
Rodius
quelle
Dies gibt mir Fehler, siehe aktualisierte Frage oben
Akshay Lokur
Woher bekommen Sie Ihren Router oder Ihre Verlaufsstütze? Stellen Sie sicher, dass Sie es von Ihrer übergeordneten Komponente oder Seite (z. B. console.log (this.props) in der Renderfunktion erhalten, und überprüfen Sie, ob Sie die Router-Requisite drucken, um sie verwenden zu können Sie haben keinen Router in Ihrer Komponente.
Rodius
0

Einfach benutzen

<span onClick={() => this.props.history.goBack()}>Back</span>
IamMHussain
quelle
0

Hoffe das hilft jemandem:

import React from 'react';
import * as History from 'history';
import { withRouter } from 'react-router-dom';

interface Props {
  history: History;
}

@withRouter
export default class YourComponent extends React.PureComponent<Props> {

  private onBackClick = (event: React.MouseEvent): void => {
    const { history } = this.props;
    history.goBack();
  };

...
Nick Bristol
quelle
0

Vielleicht kann das jemandem helfen.

Ich habe die history.replace()Umleitung verwendet. Als ich versuchte, sie zu verwenden history.goBack(), wurde ich vor der Seite, mit der ich gearbeitet habe, zur vorherigen Seite gesendet. Also habe ich die Methode geändert history.replace(), history.push()damit der Verlauf gespeichert werden kann und ich zurückkehren kann.

Julia Ramos
quelle
0

Ich bin mir nicht sicher, ob jemand anderes auf dieses Problem gestoßen ist oder dies möglicherweise sehen muss. Aber ich habe ungefähr 3 Stunden damit verbracht, dieses Problem zu lösen:

Ich wollte ein einfaches goBack () auf Knopfdruck implementieren. Ich dachte, ich hätte einen guten Start hingelegt, weil meine App.js bereits im Router enthalten war und ich {BrowserRouter als Router} aus 'react-router-dom' importierte. ... Da ich mit dem Router-Element das Verlaufsobjekt bewerten kann.

Ex:

import React from 'react';
import './App.css';
import Splash from './components/Splash';
import Header from './components/Header.js';
import Footer from './components/Footer';
import Info from './components/Info';
import Timer from './components/Timer';
import Options from './components/Options';
import { BrowserRouter as Router, Route } from 'react-router-dom';
function App() {
  return (
    <Router>
      <Header />
      <Route path='/' component={Splash} exact />
      <Route path='/home' component={Info} exact />
      <Route path='/timer' component={Timer} exact />
      <Route path='/options' component={Options} exact />
      <Footer />
    </Router>
  );
}
export default App;

ABER das Problem war auf meinem Nav-Modul (einer untergeordneten Komponente), ich musste '{withRouter} von' react-router-dom 'importieren;' und erzwingen Sie dann einen Export mit:

export default withRouter(Nav);

Ex:

import React from 'react';
import { withRouter } from 'react-router-dom';
class Nav extends React.Component {
    render() {
        return (
            <div>
                <label htmlFor='back'></label>
                <button id='back' onClick={ () => this.props.history.goBack() }>Back</button>
                <label htmlFor='logOut'></label>
                <button id='logOut' ><a href='./'>Log-Out</a>            
</button>
            </div>
        );
    }
}
export default withRouter(Nav);

Zusammenfassend wurde withRouter aufgrund eines bekannten Problems in React erstellt, bei dem in bestimmten Szenarien, in denen die Vererbung von einem Router abgelehnt wird, ein erzwungener Export erforderlich ist.

user14199788
quelle