react-router (v4) jak wrócić?


91

Próbuję wymyślić, jak mogę wrócić do poprzedniej strony. ja używam[react-router-v4][1]

Oto kod, który skonfigurowałem na mojej pierwszej stronie docelowej:

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

Aby przejść na kolejne strony, po prostu robię:

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

Jak jednak mogę wrócić do poprzedniej strony? Próbowałem kilku rzeczy, takich jak wymienione poniżej, ale bez powodzenia: 1.this.props.history.goBack();

Daje błąd:

TypeError: null nie jest obiektem (ocena „this.props”)

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

Daje błąd:

TypeError: null nie jest obiektem (ocena „this.context”)

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

Daje błąd:

TypeError: null nie jest obiektem (ocena „this.props”)

Umieszczając Page1kod tutaj poniżej:

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;

Jakich kilku rzeczy próbowałeś?
Vivek Doshi,

3
spróbuj this.props.history.goBack(); github.com/ReactTraining/react-router/blob/ ...
baskax

@VivekDoshi: Dodano to, co wypróbowałem, wraz z napotkanymi błędami
Akshay Lokur

@AkshayLokur, czy możesz przesłać pełny kod, z którego próbujesz wykonać this.props.history.goBack () ;?
Vivek Doshi,

@VivekDoshi: Gotowe, proszę spojrzeć, dzięki
Akshay Lokur

Odpowiedzi:


127

Myślę, że problem dotyczy oprawy:

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>

Jak założyłem przed wysłaniem kodu:

constructor(props) {
    super(props);
    this.handleNext = this.handleNext.bind(this);
    this.handleBack = this.handleBack.bind(this); // you are missing this line
}

nie działa, gdy przycisk Wstecz przeglądarki jest wciśnięty i włączony componentDidUpdatei window.onpopstate?
jmunsch

27
this.props.history.goBack();

To jest poprawne rozwiązanie dla React-router v4

Ale jedną rzeczą, o której powinieneś pamiętać, jest to, że musisz się upewnić, że this.props.history istnieje.

Oznacza to, że musisz wywołać tę funkcję this.props.history.goBack();wewnątrz komponentu, który jest opakowany przez <Route />

Jeśli wywołasz tę funkcję w komponencie znajdującym się głębiej w drzewie komponentów, nie zadziała.

EDYTOWAĆ:

Jeśli chcesz mieć obiekt historii w komponencie, który jest głębiej w drzewie komponentów (który nie jest zawijany przez <Route>), możesz zrobić coś takiego:

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

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

export default withRouter(Demo);

Więc jak to działa? Jak możesz cofnąć się do historii z dowolnego miejsca?
Felipe

@Felipe Możesz wrócić z dowolnego miejsca. Chodzi mi tylko o to, że musisz dodać ten wiersz kodu w komponentach kontenera, aby uzyskać obiekt "historii", nie używaj tego wiersza kodu z komponentów prezentacyjnych, które nie są opakowane przez Route ( medium.com/@dan_abramov / smart-and-dumb-components-7ca2f9a7c7d0 )
Hoang Trinh

@Felipe: Cześć, sprawdź moją zredagowaną odpowiedź. Myślę, że to odpowiada na twoje pytanie.
Hoang Trinh

Dziękuję za edycję withRouter, która rozwiązała problem.
Matthew Rideout

17

Do użytku z React Router v4 i komponentem funkcjonalnym w dowolnym miejscu w drzewie domeny.

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

To dobre rozwiązanie, ponieważ nie wykorzystuje metody cyklu życia. Jest to dla mnie również jaśniejsze, ponieważ oznacza to, przez co przechodzi, w tym przypadku obiekt historii.
AC Patrice

Wersja z grubą strzałą zawsze wygląda dla mnie o wiele czyściej, dzięki za to.
egdavid

9

Każda odpowiedź zawiera części całkowitego rozwiązania. Oto kompletne rozwiązanie, którego użyłem, aby działało wewnątrz komponentów głębiej niż tam, gdzie był używany Route:

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

^ Drugi wiersz jest potrzebny do importowania funkcji i eksportowania komponentu na dole strony.

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

^ Wymagana funkcja strzałki, a po prostu onClick = {this.props.history.goBack ()}

export default withRouter(MyPage)

^ zawiń nazwę komponentu słowem „withRouter ()”


5

Czy możesz podać kod, którego używasz this.props.history.push('/Page2');?

Czy wypróbowałeś metodę goBack ()?

this.props.history.goBack();

Jest wymieniony tutaj https://reacttraining.com/react-router/web/api/history

Z przykładem na żywo tutaj https://reacttraining.com/react-router/web/example/modal-gallery


To daje mi błąd, zobacz zaktualizowane pytanie powyżej
Akshay Lokur

Czy możesz również dodać kod this.props.history.push('/Page2');? Jeśli this.propstam nie jest zerowe, powinno działać.
Alfredo Re

Nic, po prostu dzwonię po kliknięciu przycisku Wstecz w moim komponencie
Akshay Lokur,

5

Oto najczystszy i najprostszy sposób rozwiązania tego problemu, który również unieważnia prawdopodobne pułapki związane z this keyword. Użyj funkcjonalnych komponentów:

import { withRouter } from "react-router-dom"; owinąć componentlub lepszy App.jsz withRouter() HOCtych marek historybędzie dostępny „app-wide”. opakowanie twojego komponentu sprawia, że history available for that specific komponent jest tylko twoim wyborem.

Więc masz:

  1. export default withRouter(App);

  2. W środowisku Redux export default withRouter( connect(mapStateToProps, { <!-- your action creators -->})(App), );powinieneś w ten sposób nawet być w stanie korzystać historyz twórców akcji.

w swoim componentwykonaj następujące czynności:

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 useHistoryjest eksportowana tylko z najnowszej wersji 5.1, react-router-domwięc pamiętaj, aby zaktualizować pakiet. Jednak nie powinieneś się martwić. o wielu problemach z this keyword.

Możesz również uczynić ten komponent wielokrotnego użytku do użycia w całej aplikacji.


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


2
Dzięki. Ale dlaczego mój komponent nie jest ponownie renderowany po przywróceniu przeglądarki?
Stephane

0

Próbować:

this.props.router.goBack()

To daje mi błąd, zobacz zaktualizowane pytanie powyżej
Akshay Lokur

skąd bierzesz router lub rekwizyt historii? Upewnij się, że pobierasz go ze swojego nadrzędnego komponentu lub strony (np. Console.log (this.props) w funkcji renderowania i sprawdź, czy drukujesz właściwość routera, aby móc go użyć. Wydaje mi się, że ty nie masz routera w swoim komponencie
Rodius,


0

Mam nadzieję, że to komuś pomoże:

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

...

0

Może to komuś pomoże.

history.replace()Używałem do przekierowania, więc kiedy próbowałem użyć history.goBack(), zostałem wysłany na poprzednią stronę przed stroną, z którą pracowałem. Więc zmieniłem metodę history.replace()na, history.push()aby historia mogła zostać zapisana i mógłbym wrócić.


0

Nie jestem pewien, czy ktoś napotkał ten problem lub może potrzebować tego zobaczyć. Ale spędziłem około 3 godzin próbując rozwiązać ten problem:

Chciałem zaimplementować proste goBack () jednym kliknięciem przycisku. Pomyślałem, że to dobry początek, ponieważ mój App.js był już zapakowany w routerze i importowałem {BrowserRouter jako Router} z'reak-router-dom '; ... Ponieważ element Router pozwala mi ocenić obiekt historii.

dawny:

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;

ALE problem był z moim modułem Nav (komponent potomny), musiałem 'zaimportować {withRouter} z'reak-router-dom'; ' a następnie wymuś eksport za pomocą:

export default withRouter(Nav);

dawny:

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

Podsumowując, withRouter powstał z powodu znanego problemu w React, gdzie w pewnych sytuacjach, gdy odmawia się dziedziczenia z routera, konieczny jest wymuszony eksport.


0

Możesz użyć history.goBack()w komponencie funkcjonalnym. Takie jak to.

import { useHistory } from 'react-router';
const component = () => { 
  const history = useHistory();

  return (
   <button onClick={() => history.goBack()}>Previous</button>
  )
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.