1

Assuming I am within an edit form page that has the url route of /person/edit/123

Within my react app, I also have a website logo at the top left of my app that when clicked, returns the user to the url route /home

Using react-router-dom v6 or some other means, I need to be able to check that when a user is within an edit page and decides to click on the website logo, I need to prompt the user that changes have been made and provide some message that has a "Leave page yes/no dialog"

Unsure what approach to take inorder to accomplish the above.

I have seen other threads within SO but they are using older versions of react-router-dom.

Any guidance would be great.

UPDATE: Code used but didn't seem to work:

  useEffect(() => {
    window.addEventListener('beforeunload', function (e) {
      var confirmationMessage =
        'It looks like you have been editing something. ' +
        'If you leave before saving, your changes will be lost.';

      (e || window.event).returnValue = confirmationMessage; //Gecko + IE
      return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
    });
  }, []);
ArthurJ
  • 777
  • 1
  • 14
  • 39
  • Does this answer your question? [Warn user before leaving web page with unsaved changes](https://stackoverflow.com/questions/7317273/warn-user-before-leaving-web-page-with-unsaved-changes) – Someone Special Oct 20 '22 at 11:00
  • @SomeoneSpecial - just tried this and I need it to work specifically within a React app and it didn't seem to work. I will post the code that I added to my component to my question above. – ArthurJ Oct 20 '22 at 11:15
  • Listening for the `beforeunload` event only handles *some* of the cases, i.e. when the page is reloaded. IIRC it doesn't care if you are simply navigating around within the page. The "page" here is your ***entire*** React app running as a Single Page App. You should also conditionally block navigation actions when the page is "dirty". Does this [answer](/a/74106847/8690857) help in this regard? If it looks more like what you are looking for I can try to cobble together a more complete example. – Drew Reese Oct 20 '22 at 15:51
  • @DrewReese - I took a look at that other answer and not entirely sure if I really understood it. Based on this, if you are able to please cobble together a more complete example, that would be great. As part of these edit screens, I am using Formik and basically when the user enters one of these edit screens and then deviates to a different URL, I need to show a dialog box that says: "Leave Page yes/no". – ArthurJ Oct 20 '22 at 22:46
  • Upvoted, but imo, don't use React-Router, its development is consistently a disaster for developers using it. – Slbox Oct 20 '22 at 22:57
  • Actually, this [answer](/a/74065505/8690857) might actually be more useful for you. It's effectively the demo I was about to recreate for you here. It blocks navigation/page reloads when the current "page" is marked blocked, i.e. "dirty". The question is close enough to yours that this is likely a duplicate. – Drew Reese Oct 20 '22 at 23:37
  • @Slbox - I guess it doesn't have to use react-router as I was thinking of checking for a URL change. It can be something else. – ArthurJ Oct 21 '22 at 03:26
  • @DrewReese - great, I will take a look and let you know – ArthurJ Oct 21 '22 at 06:51

1 Answers1

0

This demostrate a simplified version of a complex example to manually check for dirty forms, instead of relying on unload.

Considering you have a mechanism to check for dirty forms.

e.g.

const Component = ({ text }) => {
  const [ edited, setEdited ] = useState(text)
  
  const checkDirty = () => edited !== text

  return (... my form codes here...)
}

One of the solution is to create a CustomLink component. (psuedo code)

const CustomLink = React.forwardRef(({ onClick: dirty, href }, ref) => (
  
    const beforeHref = (e) => {
       e.preventDefault();
       if (typeof dirty == "function") {
          if (!dirty()) {
             return redirect(href)
          } else {
             if (confirm("Should we redirect!")) {
               return redirect(href);
             } else {
               return null
             }
          }
       }
       redirect(href);
    
    }
    // you should probably use the link component here
    return <a href={href} onClick={beforeHref} {...rest} />
));

Then in the page you can create a link like

<CustomLink href="/somepage" onClick={checkDirty} />

PS: Of course in the overall pages, you must pass those props to your menu, and your logo.

Someone Special
  • 12,479
  • 7
  • 45
  • 76