2

By searching the internet, I finally developed a hook that allows me to detect when the user is trying to navigate to another page of the app

I'm using React Router v6, which doesn't have an easy way to do this (history and prompt have been deprecated)

I built a code sandbox where you can see it all working (it also uses Mui), you'll see my refactored version which is more understandable and uses javascript

Edit navigating-prompt

As you can see, it has a /hooks/navigationBlocker that uses UNSAFE_NavigationContext (which was developed by the same guys that developed React Router)

import * as React from 'react';
import { UNSAFE_NavigationContext } from 'react-router-dom';

export function NavigationBlocker(navigationBlockerHandler, canShowDialogPrompt) {
    const navigator = React.useContext(UNSAFE_NavigationContext).navigator;

    React.useEffect(() => {
        if (!canShowDialogPrompt) return;

        const unblock = navigator.block((tx) => {
            const autoUnblockingTx = {
                ...tx,
                retry() {
                    unblock();
                    tx.retry();
                }
            };

            navigationBlockerHandler(autoUnblockingTx);
        });

        return unblock;
    });
}

I don't understand this code much, I guess it is so because I never used anything previous to react-router-dom v6

Is there a way to do the same without the use of UNSAFE_NavigationContext, I don't know why it's unsafe as its name suggests

Rafael

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Rafael
  • 2,413
  • 4
  • 32
  • 54
  • An alternative is to create a custom router and custom history object and use [history.block](https://github.com/remix-run/history/blob/main/docs/api-reference.md#historyblockblocker-blocker). Not to be pedantic, but `history` isn't deprecated, it's just that RRDv6 doesn't directly expose it out. Also, `Prompt` wasn't deprecated, per se, it just [wasn't included in the initial v6 release. It currently isn't supported but likely will be added back](https://reactrouter.com/docs/en/v6/upgrading/v5#prompt-is-not-currently-supported). – Drew Reese Mar 03 '22 at 16:55
  • You can check my answer [here](https://stackoverflow.com/a/70000286/8690857) for creating a custom router to use a custom history object that you could then build a custom `useNavigationBlocker` hook from. The gist is that the hook just needs the same history object the routing context is using. – Drew Reese Mar 03 '22 at 16:58
  • 2
    This stopped working somewhere around v6.4 – WillSeitz Oct 24 '22 at 19:54
  • Stopped working because the API was updated to remove some internal features that this workaround relies on. See https://github.com/remix-run/react-router/issues/8139#issuecomment-1262630360 – Kildareflare Apr 19 '23 at 01:34

0 Answers0