首页 > 解决方案 > this.props.navigation.navigate() 不适用于 AppDrawerNavigator

问题描述

我在android app中遇到导航问题。单击按钮时,应用程序屏幕冻结,它不会重定向到下一个屏幕,即 createDrawerNavigator() 屏幕。从国家选择屏幕调用它。

import React, { Component } from "react";
import { View, Image, StyleSheet } from "react-native";
import AsyncStorage from "@react-native-community/async-storage";
import {
  createSwitchNavigator,
  createStackNavigator,
  createDrawerNavigator,
  createAppContainer
} from "react-navigation";
import CustomizedStatusBar from "./src/components/CustomizedStatusBar";
import Splash from "./src/screens/Splash";
import Login from "./src/screens/Login";
import CountrySelection from "./src/screens/CountrySelection";
import Dashboard from "./src/screens/Dashboard";
import ImportantNotice from "./src/screens/ImportantNotice";
import ApplicationForm from "./src/screens/ApplicationForm";
import ApplicationForm2 from "./src/screens/ApplicationForm2";
import ApplicationForm3 from "./src/screens/ApplicationForm3";
import ApplicationForm4 from "./src/screens/ApplicationForm4";
import Instructions from "./src/screens/Instructions";
import TravelHistory from "./src/screens/TravelHistory";
import TravelHistoryDetails from "./src/screens/TravelHistoryDetails";
import DownloadStamp from "./src/screens/DownloadStamp";
import LearnAbout from "./src/screens/LearnAbout";
import Advices from "./src/screens/Advices";
import TellAFriend from "./src/screens/TellAFriend";
import Contact from "./src/screens/Contact";
import SideMenu from "./src/screens/SideMenu";
import SignatureCapture from "./src/screens/SignatureCapture";
import CMS from "./src/screens/CMS";
import GLOBAL from "./src/config/constants";
import { Provider } from "react-redux";
import store from "./src/redux/store/index";
import NavigationDrawerStructure from "./src/components/NavigationDrawerStructure";
import NavigationService from "./src/config/NavigationService";

const CMSStackNavigator = createStackNavigator({
  CMS: {
    screen: CMS
  }
});

const HomeStackNavigator = createStackNavigator({
  Home: {
    screen: Dashboard
  }
});

const ApplicationFormStackNavigator = createStackNavigator({
  ApplicationForm: {
    screen: ApplicationForm,
    navigationOptions: ({ navigation }) => ({
      title: "",
      headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
      headerStyle: {
        backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
      },
      headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
    })
  }
});

const ApplicationForm2StackNavigator = createStackNavigator({
  ApplicationForm2: {
    screen: ApplicationForm2,
    navigationOptions: ({ navigation }) => ({
      title: "",
      headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
      headerStyle: {
        backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
      },
      headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
    })
  }
});

const ApplicationForm3StackNavigator = createStackNavigator({
  ApplicationForm3: {
    screen: ApplicationForm3,
    navigationOptions: ({ navigation }) => ({
      title: "",
      headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
      headerStyle: {
        backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
      },
      headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
    })
  }
});

const SignatureCaptureStackNavigator = createStackNavigator({
  SignatureCapture: {
    screen: SignatureCapture,
    navigationOptions: ({ navigation }) => ({
      title: "",
      headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
      headerStyle: {
        backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
      },
      headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
    })
  }
});

const ApplicationForm4StackNavigator = createStackNavigator({
  ApplicationForm4: {
    screen: ApplicationForm4,
    navigationOptions: ({ navigation }) => ({
      title: "",
      headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
      headerStyle: {
        backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
      },
      headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
    })
  }
});

const TravelHistoryStackNavigator = createStackNavigator({
  TravelHistory: {
    screen: TravelHistory
  }
});

const TravelHistoryDetailsStackNavigator = createStackNavigator({
  TravelHistoryDetails: {
    screen: TravelHistoryDetails
  }
});

const DownloadStampStackNavigator = createStackNavigator({
  DownloadStamp: {
    screen: DownloadStamp,
    navigationOptions: ({ navigation }) => ({
      title: "IMMIGRATION STAMP",
      headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
      headerStyle: {
        backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
      },
      headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
    })
  }
});

const TellAFriendStackNavigator = createStackNavigator({
  TellAfriend: {
    screen: TellAFriend,
    navigationOptions: ({ navigation }) => ({
      title: "TELL A FRIEND",
      headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
      headerStyle: {
        backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
      },
      headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
    })
  }
});

const AppDrawerNavigator = createDrawerNavigator(
  {
    home: {
      screen: HomeStackNavigator
    },
    application_form: {
      screen: ApplicationFormStackNavigator,
      navigationOptions: {
        drawerLabel: "",
        drawerIcon: ({ tintColot }) => (
          <Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
        )
      }
    },
    application_form2: {
      screen: ApplicationForm2StackNavigator,
      navigationOptions: {
        drawerLabel: "",
        drawerIcon: ({ tintColot }) => (
          <Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
        )
      }
    },
    application_form3: {
      screen: ApplicationForm3StackNavigator,
      navigationOptions: {
        drawerLabel: "",
        drawerIcon: ({ tintColot }) => (
          <Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
        )
      }
    },
    signature_capture: {
      screen: SignatureCaptureStackNavigator,
      navigationOptions: {
        drawerLabel: "",
        drawerIcon: ({ tintColot }) => (
          <Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
        )
      }
    },
    application_form4: {
      screen: ApplicationForm4StackNavigator,
      navigationOptions: {
        drawerLabel: "",
        drawerIcon: ({ tintColot }) => (
          <Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
        )
      }
    },
    travel_history: {
      screen: TravelHistoryStackNavigator
    },
    travel_history_details: { screen: TravelHistoryDetailsStackNavigator },
    download_stamp: {
      screen: DownloadStampStackNavigator,
      navigationOptions: {
        drawerLabel: "IMMIGRATION STAMP",
        drawerIcon: ({ tintColot }) => (
          <Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
        )
      }
    },
    tellafriend: {
      screen: TellAFriendStackNavigator,
      navigationOptions: {
        drawerLabel: "TELL A FRIEND",
        drawerIcon: ({ tintColot }) => (
          <Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
        )
      }
    },
    cms: {
      screen: CMSStackNavigator
    }
  },
  {
    contentComponent: SideMenu
  }
);

export default class App extends Component {
  constructor(props) {
    super(props);
  }

  componentWillMount() {}

  componentDidMount() {}

  getPreferenceInfo = async () => {
    const isLoggedIn = await AsyncStorage.getItem(
      GLOBAL.PREFERENCE_STORAGE_KEY.IS_LOGGED_IN
    );
    const isLanguageSelected = await AsyncStorage.getItem(
      GLOBAL.PREFERENCE_STORAGE_KEY.IS_LANGUAGE_SELECTED
    );

    return { isLoggedIn: isLoggedIn, isLanguageSelected: isLanguageSelected };
  };

  render() {
    const AppSwitchNavigator = createSwitchNavigator(
      {
        SplashScreen: { screen: Splash },
        LoginScreen: { screen: Login },
        CountryScreen: { screen: CountrySelection },       
        DashboardScreen: { screen: AppDrawerNavigator }
      },
      {
        initialRouteName: "AppScreen"
      }
    );
    const AppContainer = createAppContainer(AppSwitchNavigator);

    return (
      <Provider store={store}>
        <View style={{ flex: 1 }}>
          <CustomizedStatusBar />
          <AppContainer />
        </View>
      </Provider>
    );
  }
}

const styles = StyleSheet.create({
  bg: {
    width: "100%",
    height: "100%"
  }
});


// Calling it from CountrySelection.js (CountryScreen)


import React, { Component } from "react";
import {
  View,
  Text,
  StyleSheet,
  Image,
  Keyboard,
  TouchableWithoutFeedback,
  TouchableOpacity,
  SafeAreaView,
  KeyboardAvoidingView,
  ActivityIndicator,
  Alert
} from "react-native";
import AsyncStorage from "@react-native-community/async-storage";
import { StackActions, NavigationActions } from "react-navigation";
import CustomInputBox from "../components/CustomInputBox";
import GLOBAL from "../config/constants";
import { connect } from "react-redux";
import {
  selectCountryWithIndex,
  openCountrySelectionView,
  getCountries,
  openLanguageSelectionView
} from "../redux/actions/index";
import CountrySelectionPicker from "../components/CountrySelectionPicker";
import LanguageSelectionPicker from "../components/LanguageSelectionPicker";

class CountrySelection extends Component {
  constructor(props) {
    super(props);

    this.didPressSubmit = this.didPressSubmit.bind(this);
    this.navigateAfterFinish = this.navigateAfterFinish.bind(this);

    this.state = {
      isLoading: true,
      animating: false,
      selectedCountry: null,
      stores: []
    };
  }

  static navigationOptions = {
    header: null
  };

  navigateAfterFinish = screen => {
    const resetAction = StackActions.reset({
      actions: [NavigationActions.navigate({ routeName: "DashboardScreen" })]
    });

    this.props.navigation.dispatch(resetAction);
  };

  getSelectedCountryInfo = async () => {
    try {
      let value = await AsyncStorage.getItem(
        GLOBAL.PREFERENCE_STORAGE_KEY.SELECTED_COUNTRY
      );
      let selectedIndex = await AsyncStorage.getItem(
        GLOBAL.PREFERENCE_STORAGE_KEY.SELECTED_COUNTRY_INDEX
      );
      return { selectedCountry: value, selectedIndex: selectedIndex };
    } catch (e) {
      console.log(e);
    }
  };

  onSelectLanguage = async (langCode, langId) => {
    // Alert.alert(
    //   "Error",
    //   langCode + "==" + langId,
    //   [
    //     {
    //       text: "OK"
    //     }
    //   ],
    //   { cancelable: false }
    // );
    try {
      await AsyncStorage.setItem(
        GLOBAL.PREFERENCE_STORAGE_KEY.SELECTED_COUNTRY,
        JSON.stringify(this.props.countrySelectionReducers.selectedCountry)
      );
      await AsyncStorage.setItem(
        GLOBAL.PREFERENCE_STORAGE_KEY.SELECTED_COUNTRY_LANGUAGE_CODE,
        langCode
      );
      await AsyncStorage.setItem(
        GLOBAL.PREFERENCE_STORAGE_KEY.SELECTED_COUNTRY_LANGUAGE_CODE_ID,
        langId
      );
      await AsyncStorage.setItem(
        GLOBAL.PREFERENCE_STORAGE_KEY.IS_LANGUAGE_SELECTED,
        "true"
      );

      return true;
    } catch (e) {
      // Alert.alert(
      //   "Error",
      //   e,
      //   [
      //     {
      //       text: "OK"
      //     }
      //   ],
      //   { cancelable: false }
      // );
      console.log(e);
      return false;
    }
  };

  getAllDatas = () => {
    AsyncStorage.getAllKeys((err, keys) => {
      AsyncStorage.multiGet(keys, (err, stores) => {
        this.setState({ stores });
      });
    });
  };

  didPressSubmit = () => {
    this.props.navigation.navigate("DashboardScreen");
  };

  componentWillMount() {}

  componentDidMount() {
    this.props.getCountries();
    this.getAllDatas();

    // this.getSelectedCountryInfo().then(data => {
    //   this.props.selectCountryWithIndex(
    //     JSON.parse(data.selectedCountry),
    //     parseInt(data.selectedIndex)
    //   );
    // });
  }

  render() {
    const { navigate } = this.props.navigation;
    return (
      <KeyboardAvoidingView behavior={"padding"} style={{ flex: 1 }}>
        <View style={{ flex: 1 }}>
          <SafeAreaView style={{ flex: 1 }}>
            <TouchableWithoutFeedback
              onPress={Keyboard.dismiss}
              accessible={false}
            >
              <View style={styles.container}>
                <Image style={styles.bg} source={GLOBAL.LOGIN_BGIMG} />
                <View style={styles.formContainer}>
                  <Text style={styles.textContainer}>
                    {GLOBAL.SELECT_COUNTRY}
                  </Text>
                  <View style={{ flex: 1 }}>
                    <CustomInputBox
                      icon={
                        this.props.countrySelectionReducers.selectedCountry !==
                        null
                          ? {
                              uri: this.props.countrySelectionReducers
                                .selectedCountry.country_logo
                            }
                          : null
                      }
                      leftInputIconStyle={
                        this.props.countrySelectionReducers.selectedCountry !==
                        null
                          ? {
                              width: 32,
                              height: 20,
                              borderWidth: 0.5,
                              borderColor: "#c6c6c6"
                            }
                          : null
                      }
                      keyboardType="default"
                      returnKeyType="next"
                      showPlaceholder={false}
                      _placeholder={GLOBAL.COUNTRY_PLACEHOLDER}
                      showRightIcon={true}
                      rightIcon={GLOBAL.COUNTRY_RIGHT_ICON}
                      defaultValue={
                        this.props.countrySelectionReducers.selectedCountry !==
                        null
                          ? this.props.countrySelectionReducers.selectedCountry
                              .country_name
                          : null
                      }
                    />
                    <TouchableOpacity
                      style={{
                        backgroundColor: "transparent",
                        top: 0,
                        bottom: 0,
                        left: 0,
                        right: 0,
                        position: "absolute"
                      }}
                      onPress={() => this.props.openCountrySelectionView()}
                    />
                  </View>
                  <View style={{ flex: 1 }}>
                    <CustomInputBox
                      icon={
                        this.props.countrySelectionReducers.selectedLanguage !==
                        null
                          ? {
                              uri:
                                GLOBAL.URL.uploads +
                                this.props.countrySelectionReducers
                                  .selectedLanguage.language_code +
                                ".png"
                            }
                          : null
                      }
                      leftInputIconStyle={
                        this.props.countrySelectionReducers.selectedLanguage !==
                        null
                          ? {
                              width: 32,
                              height: 20,
                              borderWidth: 0,
                              borderColor: "#c6c6c6"
                            }
                          : null
                      }
                      keyboardType="default"
                      returnKeyType="done"
                      showPlaceholder={false}
                      _placeholder={GLOBAL.LANGUAGE_PLACEHOLDER}
                      showRightIcon={true}
                      rightIcon={GLOBAL.COUNTRY_RIGHT_ICON}
                      customStyle={{ marginTop: 20 }}
                      defaultValue={
                        this.props.countrySelectionReducers.selectedLanguage !==
                        null
                          ? this.props.countrySelectionReducers.selectedLanguage
                              .language_name
                          : null
                      }
                    />
                    <TouchableOpacity
                      style={{
                        backgroundColor: "transparent",
                        top: 0,
                        bottom: 0,
                        left: 0,
                        right: 0,
                        position: "absolute"
                      }}
                      onPress={() => this.props.openLanguageSelectionView()}
                    />
                  </View>
                  <TouchableOpacity
                    style={[styles.btn, { marginTop: 30 }]}
                    onPress={() => this.didPressSubmit()}
                  >
                    <Image
                      style={styles.btnImg}
                      resizeMode="contain"
                      source={GLOBAL.BTN_BGIMG}
                    />
                    <View style={styles.btnContainer}>
                      <Text style={styles.btnText}>{GLOBAL.LOGINBTN}</Text>
                    </View>
                  </TouchableOpacity>
                </View>
                {this.props.countrySelectionReducers.isAnimating ? (
                  <View
                    style={{
                      width: "100%",
                      height: "100%",
                      position: "absolute",
                      justifyContent: "center",
                      alignItems: "center"
                    }}
                  >
                    <View
                      style={{
                        flex: 1,
                        backgroundColor: "#000000",
                        width: "100%",
                        height: "100%"
                      }}
                      opacity={0.6}
                    />
                    <ActivityIndicator
                      style={{ alignSelf: "center", position: "absolute" }}
                      size="large"
                      color="#ffffff"
                    />
                  </View>
                ) : null}
              </View>
            </TouchableWithoutFeedback>
            <CountrySelectionPicker />
            <LanguageSelectionPicker />
          </SafeAreaView>
        </View>
      </KeyboardAvoidingView>
    );
  }
}

const mapStateToProps = state => {
  return {
    countrySelectionReducers: state.CountrySelectionReducers
  };
};

export default connect(
  mapStateToProps,
  {
    selectCountryWithIndex,
    openCountrySelectionView,
    getCountries,
    openLanguageSelectionView
  }
)(CountrySelection);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  },
  bg: {
    width: "100%",
    height: "100%"
  },
  formContainer: {
    position: "absolute",
    width: "100%",
    paddingHorizontal: 30,
    flexGrow: 1
  },
  textContainer: {
    fontSize: 20,
    fontWeight: "bold",
    color: "#ffffff",
    alignSelf: "center",
    textAlign: "center",
    marginBottom: 30
  },
  btn: {
    alignItems: "center",
    justifyContent: "center"
  },
  btnText: {
    fontSize: 20,
    fontWeight: "bold",
    color: "#ffffff",
    alignSelf: "center"
  },
  btnContainer: {
    alignItems: "center",
    justifyContent: "center",
    position: "absolute"
  },
  btnImg: {
    resizeMode: "contain",
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    height: 46
  }
});

想要将用户重定向DashboardScreenCountryScreen使用this.props.navigation.navigate("DashboardScreen"). 但它失败了。没有错误被抛出。

标签: react-nativereact-native-android

解决方案


这已解决。问题出在 hybrid-crypto-js 库上。由于导航停止,它抛出异常。


推荐阅读