react-router (v4) how to go back?

JavascriptReactjsReact Router-V4

Javascript Problem Overview


Trying to figure out how can I go back to the previous page. I am using [react-router-v4][1]

This is the code I have configured in my first landing page:

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

In order to forward to subsequent pages, I simply do:

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

However, how can I go back to previous page? Tried few things like mentioned below but no luck:

  1. this.props.history.goBack();

Gives error:

> TypeError: null is not an object (evaluating 'this.props')

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

Gives error:

> TypeError: null is not an object (evaluating 'this.context')

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

Gives error:

> TypeError: null is not an object (evaluating 'this.props')

Posting the Page1 code here below:

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;

Javascript Solutions


Solution 1 - Javascript

I think the issue is with binding:

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>

As I have assumed before you posted the code:

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

Solution 2 - Javascript

UPDATED:

Now we have hook, so we can do it easily by using useHistory

const history = useHistory()

const goBack = () => {
  history.goBack()
}

return (
  <button type="button" onClick={goBack}>
    Go back
  </button>
);

ORIGINAL POST:

this.props.history.goBack();

This is the correct solution for react-router v4

But one thing you should keep in mind is that you need to make sure this.props.history is existed.

That means you need to call this function this.props.history.goBack(); inside the component that is wrapped by < Route/>

If you call this function in a component that deeper in the component tree, it will not work.

EDIT:

If you want to have history object in the component that is deeper in the component tree (which is not wrapped by < Route>), you can do something like this:

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

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

export default withRouter(Demo);

Solution 3 - Javascript

For use with React Router v4 and a functional component anywhere in the 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);

Solution 4 - Javascript

Each answer here has parts of the total solution. Here's the complete solution that I used to get it to work inside of components deeper than where Route was used:

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

^ You need that second line to import function and to export component at bottom of page.

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

^ Required the arrow function vs simply onClick={this.props.history.goBack()}

export default withRouter(MyPage)

^ wrap your component's name with 'withRouter()'

Solution 5 - Javascript

Here is the cleanest and simplest way you can handle this problem, which also nullifies the probable pitfalls of the this keyword. Use functional components:

import { withRouter } from "react-router-dom"; wrap your component or better App.js with the withRouter() HOC this makes history to be available "app-wide". wrapping your component only makes history available for that specific component``` your choice.

So you have:

  1. export default withRouter(App);

  2. In a Redux environment export default withRouter( connect(mapStateToProps, { <!-- your action creators -->})(App), ); you should even be able to user history from your action creators this way.

in your component do the following:

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 is only exported from the latest v5.1 react-router-dom so be sure to update the package. However, you should not have to worry. about the many snags of the this keyword.

You can also make this a reusable component to use across your app.


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

Solution 6 - Javascript

Can you provide the code where you use this.props.history.push('/Page2');?

Have you tried the goBack() method?

this.props.history.goBack();

It's listed here https://reacttraining.com/react-router/web/api/history

With a live example here https://reacttraining.com/react-router/web/example/modal-gallery

Solution 7 - Javascript

If using react hooks just do:

import { useHistory } from "react-router-dom";
const history = useHistory();
history.go(-1);

Solution 8 - Javascript

UPDATE 2022 w V6

navigate(-1)

to omit the current page from history:

navigate(-1, { replace: true })

Solution 9 - Javascript

Try:

this.props.router.goBack()

Solution 10 - Javascript

Simply use

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

Solution 11 - Javascript

Hope this will help someone:

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

...

Solution 12 - Javascript

Maybe this can help someone.

I was using history.replace() to redirect, so when i tried to use history.goBack(), i was send to the previous page before the page i was working with. So i changed the method history.replace() to history.push() so the history could be saved and i would be able to go back.

Solution 13 - Javascript

I am not sure if anyone else ran into this problem or may need to see this. But I spent about 3 hours trying to solve this issue:

I wanted to implement a simple goBack() on the click of a button. I thought I was off to a good start because my App.js was already wrapped in the Router and I was importing { BrowserRouter as Router } from 'react-router-dom'; ... Since the Router element allows me to assess the history object.

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;

BUT the trouble was on my Nav (a child component) module, I had to 'import { withRouter } from 'react-router-dom';' and then force an export with:

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

in summary, withRouter was created because of a known issue in React where in certain scenarios when inheritance from a router is refused, a forced export is necessary.

Solution 14 - Javascript

You can use history.goBack() in functional component. Just like this.

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

  return (
   <button onClick={() => history.goBack()}>Previous</button>
  )
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAkshay LokurView Question on Stackoverflow
Solution 1 - JavascriptVivek DoshiView Answer on Stackoverflow
Solution 2 - Javascript0xh8hView Answer on Stackoverflow
Solution 3 - JavascriptfripperaView Answer on Stackoverflow
Solution 4 - JavascriptfoureyedravenView Answer on Stackoverflow
Solution 5 - JavascriptLawrence EaglesView Answer on Stackoverflow
Solution 6 - JavascriptAlfredo ReView Answer on Stackoverflow
Solution 7 - JavascriptTovi NewmanView Answer on Stackoverflow
Solution 8 - JavascriptDavid SView Answer on Stackoverflow
Solution 9 - JavascriptRodiusView Answer on Stackoverflow
Solution 10 - JavascriptIamMHussainView Answer on Stackoverflow
Solution 11 - JavascriptNick BristolView Answer on Stackoverflow
Solution 12 - JavascriptJulia RamosView Answer on Stackoverflow
Solution 13 - Javascriptuser14199788View Answer on Stackoverflow
Solution 14 - JavascriptZeeshan SafdarView Answer on Stackoverflow