19

There seems to be no API way to detect if you can go back from the current page in an app. One can check the history length, but that includes the forward and backward stack.

I want to display the back button only when the user actually can go back.

philk
  • 1,615
  • 13
  • 28

4 Answers4

5

You can do it by checking history.action if its value is POP, then there is no route to go back. That's the only way I found.

<Button
  onClick={() => {
    if (history.action !== 'POP') history.goBack();
  }}
  disabled={history.action === 'POP'}
/>
Haseeb Anwar
  • 320
  • 4
  • 9
1

I think I found a workaround

There is onpopstate event:

Calling history.pushState() or history.replaceState() won't trigger a popstate event. The popstate event is only triggered by performing a browser action, such as clicking on the back button (or calling history.back() in JavaScript), when navigating between two history entries for the same document.

And I checked it: react router saves at state a key property: On history walking it may contains a data like: event.state: {key: "jr2go2", state: undefined}

And when we go back to last page on wich we entered the site or app, this state property will be null: event.state: null ,

So we can handle it with redux + rxjs (for example) like this:

// epic
export const handleHistoryWalkEpic = () =>
  fromEvent<PopStateEvent>(window, 'popstate')
  .pipe(
    map(event => setCanGoBack(!!event.state)),
  )

// reducer
case NavigationBarActionsTypes.SET_CAN_GO_BACK:
  return {
    ...state,
    canGoBack: action.payload.canGoBack,
  }

And you should set canGoBack to true on any push history action, it's possible with your any router handler component:

componentWillUpdate(nextProps: any) {
    let { location } = this.props;

    if (nextProps.history.action === 'PUSH') {
      this.props.setCanGoBack()
    }
}
-2

You can do it by checking if location.history is > 2.

Example to show or not the back button in your app:

onBack={ history.length > 2 ? () => { history.goBack() } : null }
diogopalhais
  • 310
  • 1
  • 4
  • 12
  • 2
    why `2` specifically? – ed' Sep 22 '19 at 17:15
  • 1
    @EdwardSammutAlessi if history length has 1 only that means that you don't navigate in the stack yet so you cant go back. Only if the stack have minimum 2 elements that means that you can go back in the stack navigation. Does make sense to you? – diogopalhais Sep 23 '19 at 13:20
  • 4
    It is not a solution. Assume you've opened page #1 (`history.length` is `1`), then you go to next page #2 (`history.length` is `2`), then again - to #3 (`history.length` is `3`). Now you go back from #3 to #1, `history.length` is still `3` but at page #1 you have nowhere to go back. – Dmitriy Vinokurov Feb 05 '20 at 14:16
  • 1
    I found if I open a new Chrome tab and goto a page history.length is always 2 – daihovey Apr 14 '20 at 04:25
  • but if you go back, history.length doesn't decrease – Zach Smith Oct 12 '20 at 09:36
-3

it gives 'POP' and 'PUSH' value using this.props.location.action

Mohit Verma
  • 1,384
  • 1
  • 16
  • 28