{ } }, { text: '취소합니다', style: 'destructive', onPress: () => campaginNav.dispatch(e.data.action), }, ] ); }), [campaginNav, hasUnsavedChanges] })"> { } }, { text: '취소합니다', style: 'destructive', onPress: () => campaginNav.dispatch(e.data.action), }, ] ); }), [campaginNav, hasUnsavedChanges] })"> { } }, { text: '취소합니다', style: 'destructive', onPress: () => campaginNav.dispatch(e.data.action), }, ] ); }), [campaginNav, hasUnsavedChanges] })">
const campaginNav = campaginNavigation();

const hasUnsavedChanges = Boolean(title);
useEffect(() => {
    campaginNav.addListener('beforeRemove', (e) => {
        if (!hasUnsavedChanges) {
            return;
        }
        e.preventDefault();

        Alert.alert(
            '정말 취소하시겠어요?',
            '현재 입력된 내용이 전부 사라집니다.',
            [
                { text: "아니오", style: 'cancel', onPress: () => { } },
                {
                    text: '취소합니다',
                    style: 'destructive',
                    onPress: () => campaginNav.dispatch(e.data.action),
                },
            ]
        );
    }), [campaginNav, hasUnsavedChanges]
})

버그

경고창이 2번 뜨는 버그가 발생하였다 ㅜㅜㅠㅠ

처음 title를 수정할 때는 괜찮지만, 또 수정하면 경고창이 2번 나온다..

진짜 문제점은!!

} 를 잘못 닫아서 뒤에 [campaginNav, hasUnsavedChanges] 디팬더시가 먹히길 않았다.

useEffect(() => { navigation.addLister(...), []})
// 더 간단히 보면
useEffect(() => {})

요런 형태가 되어버린 것이다.

따라서 title이 바뀌면 useEffect가 또 실행 된다 😭

최종 코드

preventGoBack.ts

import React from 'react'
import { Alert } from 'react-native'
import { useNavigation } from '@react-navigation/core';

interface Props {
    hasUnsavedChanges: boolean,
}

const perventGoBack = ({ hasUnsavedChanges }: Props) => {
    const navigation = useNavigation();

    React.useEffect(() => {
        navigation.addListener('beforeRemove', (e) => {
            if (!hasUnsavedChanges) return;

            e.preventDefault();
            Alert.alert(
                '정말 취소하시겠어요?',
                '현재 입력된 내용이 전부 사라집니다.',
                [
                    { text: "아니오", style: 'cancel', onPress: () => { } },
                    {
                        text: '취소합니다',
                        style: 'destructive',
                        onPress: () => navigation.dispatch(e.data.action),
                    },
                ]
            );
        })
    }, [hasUnsavedChanges, navigation]);
}

export default perventGoBack;

활용법

const hasUnsavedChanges = Boolean(title);
perventGoBack({hasUnsavedChanges});