Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | 7x 3x 1x 3x 7x 7x 1x 4x 4x 7x 1x 1x | import { useEffect } from 'react'
import { useBlocker } from 'react-router-dom'
export interface DirtyGuardOptions {
isDirty: boolean
submitted: boolean
ownPathname?: string
}
export interface DirtyGuardResult {
isBlocked: boolean
confirmNavigation: () => void
cancelNavigation: () => void
}
export function useDirtyGuard({
isDirty,
submitted,
ownPathname,
}: DirtyGuardOptions): DirtyGuardResult {
const blocker = useBlocker(
({ currentLocation, nextLocation }) => {
if (!isDirty || submitted) return false
const current = ownPathname ?? currentLocation.pathname
return current === nextLocation.pathname
},
)
useEffect(() => {
if (!isDirty || submitted) return
function handleBeforeUnload(e: BeforeUnloadEvent) {
e.preventDefault()
}
window.addEventListener('beforeunload', handleBeforeUnload)
return () => window.removeEventListener('beforeunload', handleBeforeUnload)
}, [isDirty, submitted])
return {
isBlocked: blocker.state === 'blocked',
confirmNavigation: () => blocker.proceed?.(),
cancelNavigation: () => blocker.reset?.(),
}
}
|