TLDR; There is no right answer
3 min read
By Einar Afiouni
December 1, 2022
We have been using React Router for a while at work, across multiple projects and spanning multiple years. React Router is one of, if not the, most popular routing library in the React world, and has been for some time.
One of the many features of React Router is (or was, foreshadowing) the
<Prompt> component which you could use to block a navigation happening based on a state, like for example if you have unsaved changes on your page and the user tries to navigate away before saving. It should be noted that this would only blocks navigation made through React Router itself, not standard anchors or browser events like reload. The latter can be blocked by using the
beforeunload event on the window object.
React Router v6 was released in November of 2021 after a series of public beta versions. During the betas the
<Prompt> component got turned into two hooks,
useBlocker. But come the final version, these two hooks got removed from the final release. A GitHub issue got opened to include these hooks back into the framework and at first they said they needed more time to finish this feature. But a year has since passed and still nothing. So what do you do?
First option was to not upgrade. And for a good while, we didn't. The React Router team has stated that v5 is still actively maintained, but at some point that won't be the case anymore and one could only hope that this one feature blocking you from upgrading has made its way into the library by then.
Second option was to use a workaround that somebody figured out. It would hook directly into an unsafe history context object. This worked, and is what we ended up doing to be able to upgrade to v6, up until the release of v6.4.0, where this context stopped being exposed.
Third option mentioned by the React Router team is to develop the website in such a way where you don't need to block the users navigation. Either by saving state in localstorage or autosaving, but this isn't always possible, and for us this wasn't really a viable option.
So now we're stuck on 6.3.0 and have to make sure not to upgrade the library above this version so that we don't break the workaround, because at this point it would be an even bigger job downgrading to v5.
I'm sorry to say I don't have an answer to the question. I feel like we're stuck between a rock and a hard place at the moment, at the mercy of the React Router team. I'm not saying we're without fault ourselves, we chose to upgrade to v6 and use the workaround.
There is a positive here though and that is that it seem like the React Router team is still looking into implementing the feature, even though at some point it looked like they had abandoned it, by their own words. So for now I'm still crossing my fingers, but I'm not holding my breath. 🤞