UNPKG

1.61 kBTypeScriptView Raw
1import type { NavigationAction } from '@react-navigation/routers';
2import { nanoid } from 'nanoid/non-secure';
3import * as React from 'react';
4import useLatestCallback from 'use-latest-callback';
5
6import type { EventListenerCallback, EventMapCore } from './types';
7import useNavigation from './useNavigation';
8import usePreventRemoveContext from './usePreventRemoveContext';
9import useRoute from './useRoute';
10
11/**
12 * Hook to prevent screen from being removed. Can be used to prevent users from leaving the screen.
13 *
14 * @param preventRemove Boolean indicating whether to prevent screen from being removed.
15 * @param callback Function which is executed when screen was prevented from being removed.
16 */
17export default function usePreventRemove(
18 preventRemove: boolean,
19 callback: (options: { data: { action: NavigationAction } }) => void
20) {
21 const [id] = React.useState(() => nanoid());
22
23 const navigation = useNavigation();
24 const { key: routeKey } = useRoute();
25
26 const { setPreventRemove } = usePreventRemoveContext();
27
28 React.useEffect(() => {
29 setPreventRemove(id, routeKey, preventRemove);
30 return () => {
31 setPreventRemove(id, routeKey, false);
32 };
33 }, [setPreventRemove, id, routeKey, preventRemove]);
34
35 const beforeRemoveListener = useLatestCallback<
36 EventListenerCallback<EventMapCore<any>, 'beforeRemove'>
37 >((e) => {
38 if (!preventRemove) {
39 return;
40 }
41
42 e.preventDefault();
43
44 callback({ data: e.data });
45 });
46
47 React.useEffect(
48 () => navigation?.addListener('beforeRemove', beforeRemoveListener),
49 [navigation, beforeRemoveListener]
50 );
51}
52
\No newline at end of file