Skip to content

Instantly share code, notes, and snippets.

@n8jadams
Last active September 25, 2020 15:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save n8jadams/3b251b4167e6a72df9cde8de9cfd6de3 to your computer and use it in GitHub Desktop.
Save n8jadams/3b251b4167e6a72df9cde8de9cfd6de3 to your computer and use it in GitHub Desktop.
Custom <Prompt /> for React Router Dom
// Instead of using the <Prompt />'s implementation
// (which uses the browser's 'confirm()',) use your own custom component!
import React, { useState, useEffect, useRef } from 'react'
import { useHistory } from 'react-router-dom'
import { Modal } from './Modal' // your custom component
interface CustomPromptProps {
when: boolean
onConfirmNavigation?: () => void
}
export function CustomPrompt({
when,
onConfirmNavigation
}: CustomPromptProps): React.ReactElement<CustomPromptProps> | null {
const history = useHistory()
const [show, setShow] = useState(false)
const completeNavigationRef = useRef((): void => {})
useEffect((): void => {
const unblock = history.block(({ pathname }, action): false | void => {
if(!when) {
unblock()
return
}
setShow(true)
completeNavigationRef.current = (): void => {
unblock()
if(action === 'POP') {
history.goBack()
} else if(action === 'PUSH') {
history.push(pathname)
} else if(action === 'REPLACE') {
history.replace(pathname)
}
}
return false
})
}, [history, when])
return show ? (
<Modal // your custom component
headingText="Change page?"
promptText="There are unsaved changes on the page. Are you sure you want to continue?"
cancelButtonText="No, cancel"
confirmButtonText="Yes, navigate"
onCancel={(): void => {
setShow(false)
}}
onConfirm={(): void => {
setShow(false)
if(onConfirmNavigation) {
onConfirmNavigation()
}
completeNavigationRef.current()
}}
/>
) : null
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment