UNPKG

@wener/console

Version:
76 lines (62 loc) 1.96 kB
/** * `useBlocker` and `usePrompt` is no longer part of react-router for the routers other than `DataRouter`. * * The previous workaround (<v6.4) was to use `block` function in `UNSAFE_NavigationContext` which is now removed. * * We're using a workaround from the gist https://gist.github.com/MarksCode/64e438c82b0b2a1161e01c88ca0d0355 with some modifications * Thanks to @MarksCode(https://github.com/MarksCode) for the workaround. */ import { useCallback, useContext, useEffect } from 'react'; import { UNSAFE_NavigationContext as NavigationContext } from 'react-router'; function useConfirmExit(confirmExit: () => boolean, when = true) { const { navigator } = useContext(NavigationContext); useEffect(() => { if (!when) { return; } const go = navigator.go; const push = navigator.push; navigator.push = (...args: Parameters<typeof push>) => { const result = confirmExit(); if (result !== false) { push(...args); } }; navigator.go = (...args: Parameters<typeof go>) => { const result = confirmExit(); if (result !== false) { go(...args); } }; return () => { navigator.push = push; navigator.go = go; }; }, [navigator, confirmExit, when]); } export function usePrompt(message: string, when = true, onConfirm?: () => void, legacy = false) { const warnWhenListener = useCallback( (e: { preventDefault: () => void; returnValue: string }) => { e.preventDefault(); e.returnValue = message; return e.returnValue; }, [message], ); useEffect(() => { if (when && !legacy) { window.addEventListener('beforeunload', warnWhenListener); } return () => { window.removeEventListener('beforeunload', warnWhenListener); }; }, [warnWhenListener, when, legacy]); const confirmExit = useCallback(() => { const confirm = window.confirm(message); if (confirm && onConfirm) { onConfirm(); } return confirm; }, [message]); useConfirmExit(confirmExit, when); }