2

In one of my React projects I have a simple form that tracks changes. I don't want that the user simply can leave the current page when unsaved changes would get lost.

If the user wants to navigate away from the page, he should get informed by a popup, that by proceeding changes are lost.

I thought to tackle this problem by using a custom hook that tracks outside clicks of my component. If a link is being clicked (outside of my ref), the redirection should be postponed, maybe until the user confirms at the popup that changes can be indeed lost. Then, a redirection should occur.

My custom hook looks like that

   const useLeaveHook = (ref) => {
      useEffect(() => {
        function handleLeaveFunction(event) {
          const handleLinkClickBehaviour = (target) => {

            // modify the click behavior. If we are on the page click listeners are not allowed
            target.onclick=(e) => {
              e.preventDefault();
            }
          }
      
          if (ref.current && !ref.current.contains(event.target)) {
            let target = event.target;

            // look if parent is a anchor element. If so, call the handleFunction.
            // Then, the onclick handler will be modified via handleLinkClickBehaviour.
            while (target && target.nodeName !== 'A') {
              target = target.parentNode
            }

            if (target) {
              handleLinkClickBehaviour(target);
            }
          }
        }

        document.addEventListener("mousedown", handleLeaveFunction);
        return () => {
          document.removeEventListener("mousedown", handleLeaveFunction);
        };
      }, [ref]);
    }

The problem is now: I work with 'react-router-dom' and I don't wan't to manipulate my onclick listeners, that's a no go. (Thus, on page leave, I could revert the click behavior)

Also, I somehow have to store the redirection state after the user executes the popup, such that the user will be redirected to the desired route.

I have no idea how I could do this. It is important that this is a solution that works with react-router-dom.

Chris
  • 75
  • 1
  • 5
  • Check out [this answer](https://stackoverflow.com/a/7317311/10536222) It's in Vanilla JS but sure you can make it work in your case – ZimGil Oct 12 '20 at 08:29

0 Answers0