134

On early versions we can go back to previous route using history.

history.goBack()

How I can achieve that with v6 of react-router-dom?

Hamza Khursheed
  • 2,399
  • 2
  • 15
  • 17
  • 1
    https://github.com/ReactTraining/react-router/blob/dev/docs/advanced-guides/migrating-5-to-6.md#use-navigate-instead-of-history Looks like it might be on `useNavigate` – Zac Anger Jan 29 '21 at 04:18
  • 2
    This is great and all. How do you use the back and forward buttons of the browser? They are not detecting the previous route in the stack for some reason. – yosemeti Feb 22 '22 at 16:39

8 Answers8

285

Try this approach

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

function YourApp() {
  const navigate = useNavigate();

  return (
    <>
      <button onClick={() => navigate(-1)}>go back</button>
    </>
  );
}
Pedro Cunha
  • 2,866
  • 1
  • 6
  • 5
55

in V6,

import { useNavigate } from 'react-router-dom';
 
function App() {
  const navigate = useNavigate();
 
  return (
    <>
      <button onClick={() => navigate(-2)}>Go 2 pages back</button>
      <button onClick={() => navigate(-1)}>Go back</button>
      <button onClick={() => navigate(1)}>Go forward</button>
      <button onClick={() => navigate(2)}>Go 2 pages forward</button>
    </>
  );
}
Sanish Joseph
  • 2,140
  • 3
  • 15
  • 28
41

Just in case anyone gets here like I did trying to navigate back OR navigate somewhere else if you can't navigate back (e.g. link opened in new tab), there doesn't seem to be any way of verifying the history with react-router in v6. However it seems you can access window.history.state which has an idx property that is zero if you're at the start of the history stack.

It's possible there are some gotchas around it that I haven't hit up against, but it's working for me:

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

// ...

const navigate = useNavigate();

// ...

if (window.history.state && window.history.state.idx > 0) {
    navigate(-1);
} else {
    navigate('/', { replace: true }); // the current entry in the history stack will be replaced with the new one with { replace: true }
}
Fantomiald
  • 55
  • 1
  • 11
Gee
  • 1,058
  • 9
  • 12
  • Unfortunately, this is not 100% reliable. Take with a grain of salt. `window.history.state.idx` is not always defined, even when routing within the app. – Taylor Buckner Aug 30 '23 at 13:41
  • @TaylorBuckner can you give an idea of what circumstances can cause it to be undefined? I've used it in several react apps and have yet to come across a scenario where it's undefined. – Gee Aug 30 '23 at 14:22
17

In old versions of react-router-dom there exists functions pop

you can reach them like:

const history = useHistory();
history.pop()

now in v6 you can use function useNavigate

const navigate = useNavigate();
navigate(-1) // you will go one page back
navigate(-2) // you will go two pages back
Abdulrahim Klis
  • 388
  • 3
  • 9
10

There is another way using a delta (number) in react-router Links v6 :

const BackButton = () => {
  return (
    <Link to={-1}>
      Back
    </Link>
  );
};

Unfortunately there is a type error in typescript, Link component does not accept numbers, but still it works.

Stephane L
  • 2,879
  • 1
  • 34
  • 44
5

If you want to navigate back or else where you can try this:

 <button onClick={() => navigate(-1) || navigate('/dashboard')}>
    Go back or Dashboard
  </button>
Dipanjan Panja
  • 396
  • 4
  • 12
  • clever! do you know where in the docs can I reference this approach? – Null isTrue Oct 21 '22 at 17:46
  • You can find usage of navigate(-1) in the v5 to v6 migration [here](https://reactrouter.com/en/main/upgrading/v5#use-usenavigate-instead-of-usehistory) or in the [v6 docs here](https://reactrouter.com/en/main/hooks/use-navigate) – Clifford Fajardo Dec 21 '22 at 18:04
  • 1
    I don't think this works (`react-router-dom@6.4.2` here), because `navigate` returns `void`. I'm getting `An expression of type 'void' cannot be tested for truthiness.` – Zefir May 24 '23 at 21:32
  • navigate(-1) returns undefined so this will always navigate to '/dashboard' (tested with react-router-dom 6.8.0) – mDeram Jun 13 '23 at 09:58
2

I would like to add that sometimes, there is a condition wherein navigate(-1) will lead to the wrong page such as for redirects during authorization check.

import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
navigate(-1);

If we want to explicitly define a state where we have a previous page, we can add a "from" property in the state.

import { useLocation, useNavigate } from 'react-router-dom';
const location = useLocation();
const navigate = useNavigate();
const currentPath = location.pathname;
navigate('/login', { state: { from: currentPath } });

Here before navigating to the login page, we set the routing state to have a "from" property which is equated to the current route.

When loading the page after logging in, we check first if there is a previous route stored in the state's "from" property much like the history stack with one level.

  const state = location.state;
  if (state?.from) {
     // Redirects back to the previous unauthenticated routes
     navigate(state?.from);
  else {
     navigate('/main-page');
   }

If the "from" property is falsy, then we navigate to a default page.

Again, this is a solution where we explicity define a previous route rather than than relying on the recent item in the history.

Miguel Ormita
  • 171
  • 2
  • 3
-4
import { useEffect } from "react";
import {useNavigate } from "react-router-dom";// react-router-dom v6 version 

const SecondComponent = () =>{
const navigate = useNavigate();
  
useEffect(() => {
    navigate('/secondComponent')
  },[]);

// note: we must have to to provide path like this one 
/*
<Routes>
        <Route path="/" element={<FirstComponent/>} />
        <Route path="/secondComponent" element={<SecondComponent />} />
      </Routes>
*/

  return(
    <>
    <h2 >this is Second page</h2>
    </>
  )
}

export  default SecondComponent;
IAMNITESHPANDIT
  • 61
  • 1
  • 1
  • 5
  • 1
    This is not the correct answer. ```navigate('/secondComponent')``` navigate to another page. To go back you have to use ```navigate(-1)``` – man.in.the.jukebox Sep 06 '22 at 22:29
  • While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. – nima Oct 30 '22 at 07:37