简体   繁体   中英

Use a React Native Alert to confirm/block Back button navigation

I'm trying to prompt the user for confirmation before using the stack navigator's back button by doing something similar to this question , but the result my result seems to be different.

 const defaultGetStateForAction = SignedIn.router.getStateForAction; const asyncGetUserConfirmation = () => { return new Promise((resolve, reject) => { Alert.alert( "Discard changes?", "Your post will be lost if you confirm.", [ { text: "No, continue editing", onPress: () => { resolve(false); } }, { text: "Yes, discard changes", style: "cancel", onPress: () => { store.dispatch(setPost({})); resolve(true); } } ], { cancelable: false } ); }); }; SignedIn.router.getStateForAction = (action, state) => { if ( state && action.type === NavigationActions.BACK && Object.keys(store.getState().post).length ) { asyncGetUserConfirmation().then(continueAction => { console.log(continueAction); return continueAction ? defaultGetStateForAction(action, state) : null; }); } else { return defaultGetStateForAction(action, state); } };

When the user touches the back button, the if in SignedIn.router.getStateForAction works properly (no questions asked if post is empty, alert pops otherwise).

I expected that the user would be redirected back if continueAction were true (at the end of the snippet), however after the user interacts with the alert, the correct result is displayed on console but regardless of continueAction being true or false, the user is not navigated back.

Everything else is working as intended, so what would make return continueAction ? defaultGetStateForAction(action, state) : null; return continueAction ? defaultGetStateForAction(action, state) : null; be "ignored", without even throwing an error?

To show the confirmation before using the stack navigator's back button you can override onPress of stack navigator.

import React from "react";
import { View, Text, Alert } from "react-native";
import { HeaderBackButton } from "react-navigation";

export default class Detail extends React.Component {
  static navigationOptions = ({ navigation }) => {
    const handleClearPress = navigation.getParam("handleBackPress", () => {});
    return {
      title: "Details!",
      headerLeft: <HeaderBackButton onPress={handleClearPress} />
    };
  };

  componentDidMount() {
    // set handler method with setParams
    this.props.navigation.setParams({
      handleBackPress: this._handleBackPress.bind(this)
    });
  }

  _handleBackPress() {
    // Works on both iOS and Android
    Alert.alert(
      "Discard changes?",
      "Your post will be lost if you confirm.",
      [
        {
          text: "No, continue editing",
          onPress: () => console.log("No, continue editing")
        },
        {
          text: "Yes, discard changes",
          onPress: () => console.log("Yes, discard changes"),
          style: "cancel"
        }
      ],
      { cancelable: false }
    );
  }

  render() {
    return (
      <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
        <Text>Detail Screen</Text>
      </View>
    );
  }
}

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM