React Navigation 有提供一個 hook usePreventRemove 可以實現這個功能
官方 demo:
import { usePreventRemove } from '@react-navigation/native';
const EditTextScreen = () => {
const [text, setText] = React.useState('');
const navigation = useNavigation();
const hasUnsavedChanges = Boolean(text);
usePreventRemove(hasUnsavedChanges, ({ data }) => {
if (Platform.OS === 'web') {
const discard = confirm(
'You have unsaved changes. Discard them and leave the screen?'
);
if (discard) {
navigation.dispatch(data.action);
}
} else {
Alert.alert(
'Discard changes?',
'You have unsaved changes. Discard them and leave the screen?',
[
{ text: "Don't leave", style: 'cancel', onPress: () => {} },
{
text: 'Discard',
style: 'destructive',
onPress: () => navigation.dispatch(data.action),
},
]
);
}
});
return (
<View style={styles.content}>
<TextInput
autoFocus
style={styles.input}
value={text}
placeholder="Type something…"
onChangeText={setText}
/>
</View>
);
};但如果想要使用自定義的提醒視窗,就需要把 data.action 存在 state 中,才能在其他地方使用
import { useNavigation, usePreventRemove } from '@react-navigation/native';
const EditTextScreen = () => {
const navigation = useNavigation();
const [isModalVisible, setIsModalVisible] = useState(false);
const [pendingAction, setPendingAction] = useState(null);
usePreventRemove(hasUnsavedChanges, ({ data }) => {
setPendingAction(data.action);
setIsModalVisible(true);
});
const handleSave = async () => {
// ...
setIsModalVisible(false);
if (pendingAction) {
navigation.dispatch(pendingAction);
}
};
const handleDiscard = () => {
setIsModalVisible(false);
if (pendingAction) {
navigation.dispatch(pendingAction);
}
};
const handleContinue = () => {
setIsModalVisible(false);
};
return (
<View>
...
<ConfirmModal
isVisible={isModalVisible}
title="儲存為草稿?"
message="儲存為草稿,以便稍後編輯和發佈。"
saveText="儲存"
discardText="不儲存"
continueText="繼續編輯"
onSave={handleSave}
onDiscard={handleDiscard}
onContinue={handleContinue}
/>
</View>
)
}
![[React Native] 未儲存前離開頁面彈出提醒 1 React Native logo](https://www.may-notes.com/wp-content/uploads/2023/10/1_ub1DguhAtkCLvhUGuVGr6w.png)


![[React] Redux Toolkit Query(RTKQ) 基礎使用指南 4 RTKQ logo](https://www.may-notes.com/wp-content/uploads/2023/12/nl9bkr5l1h5ke31vkula-150x150.webp)
![[Weekly] 2025/06/02-2025/06/08 本周紀錄 9 weekly-banner](https://www.may-notes.com/wp-content/uploads/2023/10/jazmin-quaynor-18mUXUS8ksI-unsplash-150x150.jpg)