When upgrading to React-Router 6 due to some custom architecture around routing and Redux and React-Router removing the Prompt component I had to go with my custom blocking module that was based on history package. I created it within useEffect call as below:
useEffect(() => {
if (shouldBlock) {
const unblock = history.block(transition => {
const url = transition.location.pathname;
openPromptDialog(url, unblock);
});
}
}, [shouldBlock]);
Everything looked like it's working but I found some minor bug. The openPromptDialog opens a custom confirm dialog when we want to leave a page with a dirty form (shouldBlock is true). This part works, but it does not when on the page we save the form and the want to leave. The form is no longer dirty so shouldBlock is false however since it used to be true we didn't have a chance to unblock it and I can't find a way to do it.
Please note that I don't wanna rely on React-Router blocking since I don't (and can't at the moment) use Data API createBrowserRouter which is required in to use useBlocker.
You can try this to unblock variable is declared outside the if (shouldBlock) block and is accessible in the cleanup function. When the component is unmounted or when shouldBlock changes, the cleanup function will be executed, and it will call unblock if it exists. This ensures that the blocking is properly removed even if shouldBlock becomes false.