sandrina-p
sandrina-p

Reputation: 4160

React Router — Go back using <Link>

In React Router v6, how can I go back to the previous page using <Link> instead of useNavigate().

// Instead of this...
<button onClick={() => navigate(-1)}>
// ...it needs to be this:
const previousPage = ???

<Link to={previousPage}>Go back</Link>

I don't know what URL to pass to the Link.

Why is it important: Changing it to <Link> would allow me to use <a href="xxxx"> instead of a <button>, which is the most accessible way of creating links between pages. (More about button vs links). For example, it allows users to:

Update: I've created a codesandbox to help you find the solution.

Update 2: Based on the answers and some research, I created a GitHub issue to react-router

Update 3: I've added my own answer below.

Upvotes: 13

Views: 24675

Answers (8)

wenzf
wenzf

Reputation: 475

Try the relative prop?!

import { NavLink } from "react-router"

<NavLink relative="path" to="..">back</NavLink>

Upvotes: 0

Ravish Agrawal
Ravish Agrawal

Reputation: 1

You can add a relative property to your link

relative="path"

<Link to=".." relative="path"> Go back</Link>

Upvotes: -1

Serhan C.
Serhan C.

Reputation: 1298

Try this one to go the previous page.

<Link to="..">Go Back</Link>

Upvotes: -1

maja
maja

Reputation: 799

As described in this answer on a different question, the way you can implement the go back behaviour with accessible links in React Router 6 is to use the location state to store the path value which you want to go back to, then read it in the component which holds the link.

// COMPONENT 1
const { pathname } = useLocation();
const navigate = useNavigate();
// either of the following
<Link to="/destination" state: { previous: pathname }>
  CLICK ME
</Link>
<Button
  onClick= {() => {
    navigate(
      `/destination`,
      { state: { previous: pathname } }
    )
  }
>
  CLICK ME
</Button>

// COMPONENT 2
const { state: { previous }} = useLocation();
<Link href={ previous }>GO BACK</Link>

Upvotes: 0

sandrina-p
sandrina-p

Reputation: 4160

As far as I know, it's impossible to have a fully accessible "Go Back" link with:

  <Link to={-1}>Go back</Link>
  // or
  <button onClick={() => navigate(-1)}>Go back</button>

It's not fully accessible for 2 reasons:

  1. Click does not work when you come directly from the first page (on mount).
  2. Right-click (open in a new tab) never works.

For 1) I found a workaround:

const router = useRouter(); // next/router

function handleGoBack() {
   // 💡 Verify if previous page exists before using router.back
    const hasPreviousPage = window.history.length > 1;

    if (hasPreviousPage) {
      router.back();
    } else {
      // fallback to a meaningful route.
      router.push("/");
    }
}

<button onClick={handleGoBack}>
  Go back
</button>

For 2) I didn't find any solution. My recommendation would be to avoid "go back" links using -1 whenever you can, in favor of using <Link> with a real URL to the possible previous page.

Upvotes: 3

Drew Reese
Drew Reese

Reputation: 202846

It's not a bug in react-router-dom@6 and not really anything a Link is meant to do, i.e. it's just an anchor tag under the hood, and links to a path as a declarative navigation action. This is fundamentally different than an imperative action like history.go(1) or history.back() (i.e. history.go(-1)) where you are imperatively saying to navigate forward/backward through the history stack.

In react-router-dom@6, however, you can navigate relative to the current path. ".." will navigate "back" one path segment for any Route components rendered within the current Routes component. I.E. from "/destiny" back to "/" with the same Routes component.

Example:

import { Link } from 'react-router-dom';

export default function Destiny() {
  return (
    <div>
      <h1>Destiny Page</h1>
      <Link to={'..'}>Go back</Link>
      <br />
      <Link to="/">Go Home ("/")</Link>
    </div>
  );
}

Note that this isn't the equivalent of navigate(-1) as it isn't transitioning through the history stack, so it's not a true back navigation. If you want to do a true back navigation then you'll want to add an onClick handler to the Link and prevent the default event action and handle issuing an imperative back navigation.

Example:

import { useNavigate, Link } from 'react-router-dom';

export default function Destiny() {
  const navigate = useNavigate();

  return (
    <div>
      <h1>Destiny Page</h1>
      <Link
        to={'..'}
        onClick={(e) => {
          e.preventDefault();
          navigate(-1);
        }}
      >
        Go back (-1)
      </Link>
      <br />
      <Link to="/">Go Home ("/")</Link>
    </div>
  );
}

Edit react-router-go-back-using-link

Upvotes: 11

HiB
HiB

Reputation: 33

This might work...

let url = '\\peviouspagename.js';
let element = <Link to={url}>Go Back</Link>

Place anywhere before your function...

In the function, you'll have something like: <div>{element}</div> where the script is normally to go. Element is the <Link> script. State the URL separate, the page name is all it needs. You can hash <div id="hash"></div> as well by adding it to to the end like so: let url = '\\peviouspagename.js#hash'; doing so should take you directly to the that <div> onClick.

Upvotes: -2

blessedcoder
blessedcoder

Reputation: 304

<Link to={-1}>Go Back</Link> will work.

Upvotes: 3

Related Questions