Created
July 15, 2022 03:10
-
-
Save michchan/0b142324b2a924a108a689066ad17038 to your computer and use it in GitHub Desktop.
RouteLeavingGuard full implementation in TypeScript & React 16+ for Medium article ca839f5faf39
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Location } from 'history'; | |
import React, { useEffect, useState } from 'react'; | |
import { Prompt } from 'react-router-dom'; | |
import WarningDialog from './WarningDialog'; | |
interface Props { | |
when?: boolean | undefined; | |
navigate: (path: string) => void; | |
shouldBlockNavigation: (location: Location) => boolean; | |
} | |
const RouteLeavingGuard = ({ | |
when, | |
navigate, | |
shouldBlockNavigation, | |
}: Props) => { | |
const [modalVisible, setModalVisible] = useState(false); | |
const [lastLocation, setLastLocation] = useState<Location | null>(null); | |
const [confirmedNavigation, setConfirmedNavigation] = useState(false); | |
const closeModal = () => { | |
setModalVisible(false); | |
}; | |
const handleBlockedNavigation = (nextLocation: Location): boolean => { | |
if (!confirmedNavigation && shouldBlockNavigation(nextLocation)) { | |
setModalVisible(true); | |
setLastLocation(nextLocation); | |
return false; | |
} | |
return true; | |
}; | |
const handleConfirmNavigationClick = () => { | |
setModalVisible(false); | |
setConfirmedNavigation(true); | |
}; | |
useEffect(() => { | |
if (confirmedNavigation && lastLocation) { | |
// Navigate to the previous blocked location with your navigate function | |
navigate(lastLocation.pathname); | |
} | |
}, [confirmedNavigation, lastLocation]); | |
return ( | |
<> | |
<Prompt when={when} message={handleBlockedNavigation} /> | |
{/* Your own alert/dialog/modal component */} | |
<WarningDialog | |
open={modalVisible} | |
titleText="Close without saving?" | |
contentText="You have unsaved changes. Are you sure you want to leave this page without saving?" | |
cancelButtonText="DISMISS" | |
confirmButtonText="CONFIRM" | |
onCancel={closeModal} | |
onConfirm={handleConfirmNavigationClick} | |
/> | |
</> | |
); | |
}; | |
export default RouteLeavingGuard; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Prompt not available in react-router-dom v6. Any thoughts on how to fix?