React-Router (v4) як повернутися назад?


84

Намагаючись зрозуміти, як я можу повернутися на попередню сторінку. я використовую[react-router-v4][1]

Це код, який я налаштував на своїй першій цільовій сторінці:

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

Для пересилання на наступні сторінки я просто роблю:

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

Однак як я можу повернутися на попередню сторінку? Перепробував кілька речей, як зазначено нижче, але не пощастило: 1.this.props.history.goBack();

Видає помилку:

TypeError: null не є об'єктом (оцінюючи 'this.props')

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

Видає помилку:

Помилка типу: null не є об'єктом (оцінюючи 'this.context')

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

Видає помилку:

TypeError: null не є об'єктом (оцінюючи 'this.props')

Розміщення Page1коду тут нижче:

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;

Які кілька речей ви спробували?
Вівек Доші

3
спробуйте this.props.history.goBack(); github.com/ReactTraining/react-router/blob/…
baskax

@VivekDoshi: Додав те, що я спробував разом із помилками, з якими зіткнувся
Акшай Локур,

@AkshayLokur, чи не надішлеш ти, будь ласка, повний код, звідки ти намагаєшся виконати this.props.history.goBack () ;?
Вівек Доші,

@VivekDoshi: Готово, будь ласка, подивіться, дякую
Акшай Локур

Відповіді:


119

Я думаю, що проблема полягає у прив’язку:

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>

Як я припускав до того, як ви опублікували код:

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

не працює, коли натиснута кнопка повернення браузера і в componentDidUpdateі window.onpopstate?
jmunsch

25
this.props.history.goBack();

Це правильне рішення для реакційного маршрутизатора v4

Але потрібно пам’ятати одне, що вам потрібно переконатися, що this.props.history існує.

Це означає, що вам потрібно викликати цю функцію this.props.history.goBack();всередині компонента, який обгорнуто <Route />

Якщо ви викликаєте цю функцію в компоненті, який знаходиться глибше в дереві компонентів, вона не буде працювати.

РЕДАГУВАТИ:

Якщо ви хочете, щоб об'єкт історії був у компоненті, який знаходиться глибше в дереві компонентів (який не обгортається <Маршрутом>), ви можете зробити щось подібне:

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

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

export default withRouter(Demo);

То як це може працювати? Як можна повернутися в історію звідки завгодно?
Феліпе

@Felipe Ви можете повернутися звідки завгодно. Я просто маю на увазі, що вам потрібно додати цей рядок коду до компонентів Container, щоб отримати об’єкт "history", не використовуйте цей рядок коду з презентаційних компонентів, який не обгорнутий маршрутом ( medium.com/@dan_abramov / smart-and-dumb-components-7ca2f9a7c7d0 )
Хоанг

@Felipe: Привіт, будь ласка, перевір мою відредаговану відповідь. Думаю, це відповідає на ваше запитання.
Хоанг Трінь,

Дякую за редагування withRouter, яке мені це виправило.
Matthew Rideout

17

Для використання з React Router v4 та функціональним компонентом у будь-якому місці Dom-дерева.

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

Це хороше рішення, оскільки воно не використовує метод життєвого циклу. Мені це також зрозуміліше, оскільки воно позначає те, що проходить, в даному випадку об'єкт історії.
AC Patrice

Версія для жирних стрілок мені завжди виглядає набагато чистішою, дякую за це.
egdavid

9

Кожна відповідь тут має частини загального рішення. Ось повне рішення, за допомогою якого я працював усередині компонентів глибше, ніж там, де використовувався Route:

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

^ Вам потрібен цей другий рядок для імпорту функції та експорту компонента внизу сторінки.

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

^ Потрібна функція стрілки проти просто onClick = {this.props.history.goBack ()}

export default withRouter(MyPage)

^ оберніть ім'я компонента на 'withRouter ()'


5

Чи можете ви надати код, де ви використовуєте this.props.history.push('/Page2');?

Ви пробували метод goBack ()?

this.props.history.goBack();

Це перераховано тут https://reacttraining.com/react-router/web/api/history

З реальним прикладом тут https://reacttraining.com/react-router/web/example/modal-gallery


Це призводить до помилки, будь ласка, дивіться оновлене запитання вище
Акшай Локур

Чи можете ви також додати код навколо this.props.history.push('/Page2');? Якщо this.propsтам немає значення null, це має спрацювати.
Альфредо Ре

Насправді нічого, я просто називаю це натисканням кнопки Назад у моєму Компоненті
Акшай Локур

4

Ось найчистіший і найпростіший спосіб вирішення цієї проблеми, який також зводить нанівець можливі підводні камені this keyword. Використовуйте функціональні компоненти:

import { withRouter } from "react-router-dom"; обернути componentабо краще App.jsз withRouter() HOCцими марками historyбути доступні «додаток-широким». упаковка вашого компонента лише робить history available for that specificкомпонент ` ` вашим вибором.

Отже, у вас є:

  1. export default withRouter(App);

  2. У середовищі Redux export default withRouter( connect(mapStateToProps, { <!-- your action creators -->})(App), );ви навіть можете мати можливість користуватися historyсвоїми творцями дій таким чином.

в вашому componentзробити наступне:

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 useHistoryекспортується лише з останньої версії 5.1, react-router-domтому не забудьте оновити пакет. Однак турбуватися не варто. про численні корчі this keyword.

Ви також можете зробити цей компонент багаторазовим для використання у вашому додатку.


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



2
Дякую. Але чому мій компонент не відтворюється повторно, коли я повертаю браузер назад?
Стефан

0

Спробуйте:

this.props.router.goBack()

Це призводить до помилки, будь ласка, дивіться оновлене запитання вище
Акшай Локур

звідки ви берете свій маршрутизатор або реквізит історії? Переконайтеся, що ви отримуєте його з батьківського компонента чи сторінки (тобто console.log (this.props) функції рендерингу, і переконайтесь, що ви друкуєте проптер маршрутизатора, щоб мати можливість ним користуватися. Мені здається, ви не має маршрутизатора у вашому компоненті.
Родіус,

0

Просто використовуйте

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

0

Сподіваюся, це комусь допоможе:

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

Можливо, це може комусь допомогти.

Я використовував history.replace()для переспрямування, тому, коли я намагався використовувати history.goBack(), я перейшов на попередню сторінку до сторінки, з якою працював. Тому я змінив метод history.replace()на те, history.push()щоб історію можна було зберегти, і я зміг би повернутися назад.


0

Я не впевнений, що хтось ще стикався з цією проблемою, або, можливо, доведеться це побачити. Але я витратив близько 3 годин, намагаючись вирішити цю проблему:

Я хотів застосувати простий goBack () натисканням кнопки. Я думав, що почав добре, оскільки мій App.js вже був загорнутий у маршрутизатор, і я імпортував {BrowserRouter as Router} з 'response-router-dom'; ... Оскільки елемент Router дозволяє мені оцінити об'єкт історії.

напр .:

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;

АЛЕ проблема в моєму модулі Nav (дочірній компонент), мені довелося "імпортувати {withRouter} з" response-router-dom "; ' а потім примусити експорт за допомогою:

export default withRouter(Nav);

напр .:

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

підсумовуючи, withRouter було створено через відому проблему в React, коли в певних сценаріях, коли відмовляють у спадкуванні від маршрутизатора, необхідний примусовий експорт.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.