Router: Implementing "Back" functionality

Created on 6 Jun 2018  路  26Comments  路  Source: reach/router

Question

How is "go back to the previous route" functionality handled in Reach Router?

enhancement

Most helpful comment

come to think of it ... maybe navigate could take an int? navigate(-1)

All 26 comments

As far as I can tell there's nothing built in. Since it uses history API, you can always do window.history.back() or window.history.go(-1) , however.

Yep, that should work just fine. Should maybe put that in the docs somewhere.

window.history.back() is working great. Thanks :)

come to think of it ... maybe navigate could take an int? navigate(-1)

Anybody wanna implement this?

  • If it's an int, call history.go(n)
  • if it's not, carry on
  • can probably skip the transitioning checks because those are just there to prevent extra items being added to the stack when a user navigates before Suspense has settled. With go we're just moving around in the stack.

I want to help with this one 馃憤. Can I?

Using window.history.back() users can leave the app, navigate(-1) should prevent that

Is it a good practice to use the window object in React?

@dydokamil There's nothing wrong with using window or other browser APIs/Objects. However you need to keep in mind that the code path would get undefined in case it's running on server (Server Side Rendering).

Since going back would usually be triggered by a click event, you can use it safely in the event listener.

Looks like this was never added, do we still want to add something to navigate to make this work? Or should we just encourage people to use the window.history.back() api?

Currently working on an app that uses reach router and am running into this issue, so just want to raise the topic again since the issue's still open. Is #197 going to be merged in sometime soon?

+1

Unfortunately, window.history.back() doesn't re render the page that was linked from , so things that need to happen on that page with a render or CDM etc don't work with this method

+1

window.history.back() isn't available when using memorySource. To prepare this and be independent of the browser (for stuff like Gatsby, maybe?), there should be a way of going back in history without window.

There's this pull request that I think adds this feature properly, but it hasn't been merged. To be completely functional, memorySource must be modified to add the history::go() method required for this to work.

I'm worried this repository is no longer maintained, though. It'd be a shame. Anyone knows what's up?

I believe your answer can be found in https://reacttraining.com/blog/reach-react-router-future/

I believe your answer can be found in https://reacttraining.com/blog/reach-react-router-future/

Ah! That explains it all. Makes a lot of sense. Perhaps the project should contain some sort of deprecation notice in favor of the new React Router. It could help close a lot of issues regarding new features and whatnot.

Many have no idea about the foreseeable future of @reach. Myself included... until now.

Thanks a lot!

197

@ryanflorence, this is still broken (even in the beta 1.3.0 version) due to the call to resolve(...) here: https://github.com/reach/router/blob/0908a5fd7d8a7d5c928a8062234ce6f5639a1962/src/index.js#L220

resolve(...) treats the argument as a string and throws an exception when trying to do a .substr

import { navigate } from "@reach/router";

const goBack = () => {
navigate(-1);
}

<a onClick={goBack} className="back-link">Back</a>

@gazgump, which version have you confirmed this to be working in?

As stated above, there is a bug with how the parameter is being handled.

"@reach/router": "^1.3.1",

https://reach.tech/router/api/navigate

You can pass a number to go to a previously visited route.

navigate(-1)

@gazgump, i know what the API docs say. But at least as of 1.3.0, that API was broken. I'll give a newer version a try =], thanks for the heads up.

@ryanflorence @gazgump @Xapphire13 I just ran into the same issues on version 1.3.3. I think the issue presents itself when attempting to use -1 with the navigate function passed in as props to the component usually used for relative navigation.

if you are using reach-router in mini-app such as iframe and you don't want to change the parent router, or if you want to store history entries in memory for testing or other platforms like Native and you are using createMemorySource non of navigate(-1) or window.history.back() or window.history.go(-1) will work, here is a hacky low-level way to replace navigate for numbers.

const source = createMemorySource('/default')
// will be used in reach-router provider
export const history = createHistory(source)
// will be used for navigation 
export const { navigate } = history

till "@reach/router": "^1.3.4", it doesn't provide a method for replacing state when to is a number in `navigate(to).

https://github.com/reach/router/blob/e203fe612236851a0bd3c77dba693e539a351c62/src/lib/history.js#L75-L78

here is a low-level hacky usage of reach-router for simulate back, if you are using the above setup

export const dangerouslyGoToLastRoute = async () => {
  try {
    source.history.go(-1)
    const lastRoute = source.history.entries[source.history.index].pathname
    source.history.entries.pop()
    if (lastRoute) await navigate(lastRoute, { replace: true })
  } catch (error) {
    console.log(error)
  }
}

Usage

const goToPreviousRoute = dangerouslyGoToLastRoute

const Button = () => (
  <button onClick={goToPreviousRoute} >back</button>
)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

kbrgl picture kbrgl  路  4Comments

alexluong picture alexluong  路  3Comments

michaelwiktorek picture michaelwiktorek  路  4Comments

florian-bd picture florian-bd  路  3Comments

sseppola picture sseppola  路  4Comments