Jorge Kunrath
Jorge Kunrath

Reputation: 1006

How to use useNavigate previous page without accidentally leaving my site

Problem: I'm trying to use useNavigate(-1) to go to previous page, but I just implement a way to people arrive in my SPA with a pasted link (or social media tho), so, when user tries to go back they leave my site xP.

Process: I could use useNavigate("/"), but this makes my page scroll to the top and I want to keep the previous users position, I rather not use a state with my scroll position, but if nothing else is possible or simple...

Context: is a restaurant menu ifood-like page, this problems occurs in product page and I want to go back to product list.

What I'm trying to achieve: some way to check if previous page is out of my domain and not go there, replacing with my root.

ps. I'm using "react-router-dom": "^6.0.0-beta.0"

Upvotes: 5

Views: 3141

Answers (1)

evelynhathaway
evelynhathaway

Reputation: 1887

In earlier versions of React Router DOM, there was a smarter goBack method, but in modern versions (including the v6 beta), you must use the fact that the location.key is "default" for the initial entry to the app's history.

I created an npm package that encapsulates this functionality in a simple React hook.

Install use-back

npm install use-back

Usage

import {useBack} from "use-back";

const BackButton = () => {
  const {hasBack, handleBack} = useBack();
  return (
    <button type="button" onClick={handleBack}>
      {hasBack ? "Go Back" : "Go Home"}
    </button>
  );
};

CodeSandbox Demo

Source Code

The source code is basically the following, which you can also include in your application.

const MagicalBack = () => {
  const navigate = useNavigate();
  const location = useLocation();
  const hasPreviousState = location.key !== "default";

  const handleClick = () => {
    if (hasPreviousState) {
      navigate(-1);
    } else {
      navigate("/");
    }
  };

  return (
    <button type="button" onClick={handleClick}>
      {hasPreviousState ? "Go Back" : "Go Home"}
    </button>
  );
};

CodeSandbox Demo

Upvotes: 5

Related Questions