import { useEffect, useContext } from 'react'; import { useInRouterContext, UNSAFE_NavigationContext } from 'react-router-dom'; function invariant(cond, message) { if (!cond) throw new Error(message); } export function useBlocker(blocker, when = true) { invariant(useInRouterContext(), // TODO: This error is probably because they somehow have 2 versions of the // router loaded. We can help them understand how to avoid that. `useBlocker() may be used only in the context of a component.`); let { navigator } = useContext(UNSAFE_NavigationContext); useEffect(() => { if (!when) return; let unblock = navigator.block((tx) => { let autoUnblockingTx = Object.assign(Object.assign({}, tx), { retry() { // Automatically unblock the transition so it can play all the way // through before retrying it. TODO: Figure out how to re-enable // this block if the transition is cancelled for some reason. unblock(); tx.retry(); } }); blocker(autoUnblockingTx); }); return unblock; }, [navigator, blocker, when]); }