Difficult to migrate .block() use case to v5
See original GitHub issueHi,
I use history.block to check whether the next location can be transition to. If not, do a full page load. The pseudo code looks like
const unblock = history.block((tx) => {
// canTransition is the function that checks if next location can be SPA transition to
// If false, do a full page load on next location's path
if (!canTransition()) {
return window.location.assign(nextPath);
}
unblock();
tx.retry();
});
Full code example: https://codesandbox.io/s/distracted-river-8yczz?file=/src/index.js
So depending on the result of canTransition(), it should either unblock the blocker or do a full page reload. Users shouldn’t notice much difference. This is fine except for the navigation that reloads the page. Users see something like this (Chrome):
It doesn’t make sense to our users as there isn’t any unsaved changes.
I’ve read the documentation and understand the library registers a beforeunload handler to prevent the navigation. Maybe v5’s .block is not designed for my use case.
But I am able to achieve this use case via history v4. I’ve also tried history.listen but .listen is too late as it happens at the end of applyTx
.
Any suggestion is much appreciated. 🙂
The solution I can think of is to remove window.addEventListener(BeforeUnloadEventType, promptBeforeUnload);
from the library and let consumer of the library to handle it.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:3
- Comments:5
I’ve found a hacky workaround 😬
Register our own BeforeUnloadEvent and clean up our transition blockers before history runs its check
@liamqma Thank you so much for the workaround it works perfectly well in my case too. I just had to register my own event listener before calling block which I did the other way initially.
Meanwhile I am wondering if calling the provided blockers on “beforeunload” could be something directly implemented inside history itself. I came up with this code on my side (highly inspired from react-router beta.6):
The
beforeUnloadCallback
is basically doing the trick you talked about plus calling the underlying blocker to check whether or not we should prevent the default behaviour of the browser. If we should, then we let the beforeunload handler registered by history do the blocking, otherwise we unplug it (your code).I’m wondering if such behaviour should be the default for block in history. It would made users able to say whether or not they really want to lock the tab closing. Is there a reason not to call blockers when receiving things on beforeunload?