My app has two pages: Step1
and Step2
. Step1
has a checkbox that blocks navigation if it is checked and a Next button that navigates to Step2
when clicked. Step2
has a Previous button that navigates back to Step1
when clicked.
As per this tutorial, I'm using the block
method of the createBrowserHistory
object to block route changes if the checkbox in Step1
is checked:
const unblock = useRef();
useEffect(() => {
unblock.current = history.block((tx) => {
if (block.current.checked) {
const promptMessage = "Are you sure you want to leave?";
if (window.confirm(promptMessage)) {
unblock.current();
tx.retry();
}
} else {
console.log("tfgx");
unblock.current();
tx.retry();
}
});
}, []);
I also had to set the history prop in the low-level <Router>
(not <BrowserRouter>
) to the createBrowserHistory
object, like so:
<Router history={createBrowserHistory()}>
...
</Router>
But this prevents the routes from being rendered properly. I think this may have something to do with <Switch>
not being able to read the location object properly. If I use <BrowserRouter>
, the location object looks like this: {pathname: "/step1", ... key: "7sd45"}
. But when I use <Router={createBrowserHistory()}>
, the location object looks like this {action: "PUSH", location: {pathname: "/step1", ... key: "7sd45"}}
. (I'm also getting the warning You cannot change <Router history>
.)
My desired result is to block navigation if the 'Block navigation' checkbox is checked and unblock it otherwise. If the location changes when navigation is unblocked, I would like the corresponding route to be rendered correctly.
The section on createBrowserHisory in the React Router v5 docs is sparse and there aren't many examples that make use of it, so I'd be grateful if someone could shed some light on this.
EDIT: Passing location.location
to <Switch>
seems to fix it (Updated demo). But if I call useLocation
inside Step1
and print the result (line 17-18), I get {pathname: "/step1", ... key: "7sd45"}
and not {action: "PUSH", location: {pathname: "/step1", ... key: "7sd45"}}
. Why is this?
Also, if the user attempts to go to another location when navigation is blocked, my custom prompt appears as expected ("Are you sure you want to leave" with "OK" and "Cancel" buttons). However, if they dismiss this by clicking Cancel, then the browser's own dialog box appears -
In Chrome:
In Firefox:
Is it possible to suppress the browser prompt after my prompt has been dismissed?