[React Native] 未儲存前離開頁面彈出提醒

React Native logo

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>
  )
}
guest

0 評論
最舊
最新 最多投票
內聯回饋
查看全部評論