Currently one has to use ActiveState
with a willTransitionTo
hook to know if Navigation.goBack
will do anything. It would be nice if goBack
returned a boolean that tells you wether it there's anything in history (as managed by react-router).
I would also be interested in this. However, I'm not sure what the right solution would be.
Think of a similar use case involving a list view and a detail view. Given a detail view can be visited directly by URL it won't have a meaningful previous history entry (instead it's the empty tab page in Chrome). Therefore, the classic history goBack
behaviour will not do anything meaningful when clicked. Perhaps being able to query the managed history would make sense here: If there's no previous entry, do something else in the render method or the click callback.
+1! I only use goBack
for Cancel buttons but it sucks because I don't know if the user hit page directly.
Unless you use RefreshLocation
, it's unlikely you ever want to send user to previous website.
Seems like the primary use case here is wanting to know whether or not there's anything in the history to goBack
to. Would it be enough to just have a canGoBack()
method somewhere?
+1 on canGoBack
. I would find that very useful.
:+1:
From my understanding canGoBack
something router should manage, since browsers don't seem to provide reliable/same API for this.
Should canGoBack
be scoped to current application? I think yes. If I came to Google and I'm on my initial route, I suggest it returns false
.
Should canGoBack
return true
or false
with RefreshLocation
? That's a tricky one, and while returning false
is consistent with previous point, it's not too obvious. If canGoBack
was called canGoBackWithoutRefreshing
it would make more sense, but the name sucks.
Ideas?
Should canGoBack be scoped to current application? I think yes. If I came to Google and I'm on my initial route, I suggest it returns false.
Definitely. Can't think of a use case where it would make sense to go back to an external website or empty tab. That's why we need this in the first place :)
RefreshLocation
I just read up on RefreshLocation
. Tough question. Is it even possible to determine whether the navigation is at the start of history when using it? I couldn't see any state tracking, but I'm not sure it's in there.
I think returning false
for RefreshLocation
is OK.
It just says “we can't guarantee you'll stay where you are so proceed on your own risk”.
_However_ there's yet another subtlety here. Should goBack()
do anything if canGoBack()
returns false
?
One real-world example of this happening is when transition.abort()
happens on very first route. Currently, it will kick you out of the website. If goBack()
is a no-op when canGoBack()
is false
, it will just render blank screen. What makes more sense? (Should you even be able to abort
first transition?)
Maybe we do this:
goBack
a no-op if we don't actually have any history (in the current app, ofc)goBack
trigger a warning
(so the dev has some feedback about why it didn't work)goBack()
to goBack(force=false)
so devs can force the browser to go back when they're using RefreshLocation
. Or maybe just default force=true
if we're using RefreshLocation
I think that would satisfy everyone's use cases here.
Sounds wise. Certainly satisfies mine.
What would the warning be. In my case if goBack
can't accomplish anything, I would instead like to transitionTo
another route. So essentially I need this:
if (canGoBack()) {
goBack();
} else {
transitionTo();
}
I think goBack
should return a boolean of whether action was performed.
if (!goBack()) {
transitionTo();
}
So it's goBack(force: bool = false): bool
.
@gaearon ya, that sounds good.
@mjackson Would there also be a canGoBack()
so I can determine whether I need to show a back button at all?
@ehd I don't think so. Instead, we can expose a length
property, similar to History.length
so you can do:
if (history.length > 0)
// show the back button
@mjackson Sounds good! My specific use case was this:
So length
would work here.
Thanks everyone!
Hey, it would be great if the docs could be updated accordingly, they're pretty sparse on goBack()
info right now. Was looking for this functionality just now and had to search through the issues to find it.
Care to create a PR?
Michael Jackson
@mjackson
On Fri, Dec 19, 2014 at 1:08 PM, Chris Shiplet [email protected]
wrote:
Hey, it would be great if the docs could be updated accordingly, they're
pretty sparse on goBack() info right now. Was looking for this
functionality just now and had to search through the issues to find it.—
Reply to this email directly or view it on GitHub
https://github.com/rackt/react-router/issues/408#issuecomment-67697490.
Maybe it should be propagated by the Navigation mixin.
Currently it does not return anything.
goBack: function () {
this.context.goBack();
}
@ganmor Good catch, care to submit a PR?
It's fixed in master. 62c49d2925785a4184860accdc125fdeb0ad4806
Yep jus seen that, had an old version sorry.
My mistake, fixed by #825
Is there a way to do a "canGoBack"?
@dmr try this:
handleBackClick() {
if ( this.goBack() ) {
console.log ("Can Go Back");
}
else {
console.log("Can't go back");
this.transitionTo('/'); // App root.
}
}
Thank you, this works ok for now
I am using the latest beta3 and I am trying to only show a back button if it is relevant, like so:
if (history.length > 0)
// show the back button
Is this possible in beta3 and if so, could anyone show an example of how it would work in a component?
I was trying to get this working too. See below... A hack is to save the existing window.history.length in this.state
; otherwise all previous web site/app history (i.e. if you surf YouTube before loading your app into the same browser tab) will be reflected in window.history.length
.
// In in your root component/app.
getInitialState: function() {
return {
myWindowHistoryStart: window.history.length // Could also just put this into an object, see below.
};
},
// Somewhere else in your code, to check if you should show Back button.
if ( window.history.length > this.state.myWindowHistoryStart ) {
// show the back button, i.e. setState( {isShowBackButton: true} );
}
Why even use state, since myWindowHistoryStart is static, just want to capture starting length when your app loads:
MyThing = React.createClass({
myWindowHistoryStart: window.history.length, // Could also put this in ComponentWillMount
// depending on how you want to organize things, may be more explicit that way.
render: function() {
return (
<div>
{ (window.history.length > this.myWindowHistoryStart) ? showBackButton : null }
</div>
}
});
More info on window.history:
https://developer.mozilla.org/en-US/docs/Web/API/Window/history
Update: I tried the example above, it only works the 1st time the app is loaded. Once you go to another page and back the back button will show up. Reason is window.history.length doesn't decrease when you go back in the browser (that's how it's supposed to be, it's the total history of your session in that tab).
This SO article may help explain some things: http://stackoverflow.com/questions/3588315/how-to-check-if-the-user-can-go-back-in-browser-history-or-not
I'm having some troubles with goBack()
. How can I know if the user hit the page directly in version 2.0.0?
Does it makes sense to make goBack()
smarter like suggested in this issue?
I'm not sure if this is the correct place to put this question, with everything growing so fast, sorry in advance! :)
I agree, this should be reopened as far as I can tell?
goBack does not seem to return the boolean as described above anymore. Issue should be reopened.
Please open a new issue. Much of the discussion here is pre-1.0 and is no longer relevant.
So is there actually a way to find out if goBack
is available?
It does not seem that there is a method for that any longer. I ended up
just keeping a local log of previously navigated to url. If there is none
then the user just entered the site and should not be able to go back.
On Thu, Jun 2, 2016 at 12:38 PM, Philipp Kursawe [email protected]
wrote:
So is there actually a way to find out if goBack is available?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/reactjs/react-router/issues/408#issuecomment-223399083,
or mute the thread
https://github.com/notifications/unsubscribe/AAmT7-XorhqKpZXXWZVer-rtcXIK9p_2ks5qHzFAgaJpZM4Cu4KP
.
Actually goBack returns boolean, but even when it returns false, it takes you back to the previous location, which seems to be buggy.
"Please open a new issue. Much of the discussion here is pre-1.0 and is no longer relevant."
This issue is the top Google result so I think having an answer here would be helpful.
It seems there is no longer functionality for a smart goBack
in v4?
I'm trying to create a 404 page where it has a "Go home" button if user landed from outside the app, or "Go back" button if going back in history will keep them in the app:
const NoMatch = ({ history }) => {
const canGoBackInsideApp = ???
return (
<View>
<Text>404 error</Text>
{canGoBackInsideApp
? <Button onClick={history.goBack}>
Go back
</Button>
: <Link to="/">
<Button>Go home</Button>
</Link>
}
</View>
)
}
Not sure what can be used for the ???
here; I've checked out the docs and the goBack
function no longer returns a boolean, history
no longer has a canGoBack
, and history.length
includes history from outside the app; I thought about grabbing the last location and checking lastUrl.split("/")[0].contains("appRootOfUrl")
, but there seems to be no way of getting the last location without mutating history (there used to be a history.entries
but this no longer exists as far as I can see in v4).
What is the recommended way to accomplish this in v4? I'm happy to submit a PR to the docs if someone can explain how and where it should go :) Thank you!
dispatch => {
return {
canGoBack: () => {
dispatch((window.history.length > 2 || document.referrer.length > 0 ? goBack(false) : push('/')))
}
}
Not sure, but isn't the window.history
for all URLs not only the current app ones? Or does it not contain URLs from other domains?
Hey @trevordmiller, did you figure out how to make goBack
work?
@btiwaree Nope - I switched to using Next.js with its routing system instead of React Router: https://nextjs.org
Most helpful comment
This issue is the top Google result so I think having an answer here would be helpful.
It seems there is no longer functionality for a smart
goBack
in v4?I'm trying to create a 404 page where it has a "Go home" button if user landed from outside the app, or "Go back" button if going back in history will keep them in the app:
Not sure what can be used for the
???
here; I've checked out the docs and thegoBack
function no longer returns a boolean,history
no longer has acanGoBack
, andhistory.length
includes history from outside the app; I thought about grabbing the last location and checkinglastUrl.split("/")[0].contains("appRootOfUrl")
, but there seems to be no way of getting the last location without mutating history (there used to be ahistory.entries
but this no longer exists as far as I can see in v4).What is the recommended way to accomplish this in v4? I'm happy to submit a PR to the docs if someone can explain how and where it should go :) Thank you!