首页 > 解决方案 > this.props.navigation.navigate 在屏幕中不起作用

问题描述

在我的应用程序中,我有一个已在 stackNavigator 中注册的选择语言屏幕,但我无法在其中使用 this.props.navigation.navigate 这个“选择语言屏幕”出现在应用程序首次启动时

这是index.js

import {AppRegistry} from 'react-native';
import App from './App';
import ChooseLanguage from './screens/ChooseLanguage'
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => ChooseLanguage);

这是选择语言屏幕,所以当按下可触摸的不透明度时,我调用this.props.navigation.navigate ('AppIntroScreen') 但它不起作用,它给了我这个错误: 未定义不是对象(评估 _this2.props.navigation.导航)

import React, { Component } from "react";
import {
    View,
    Text,
    StyleSheet,
    Image, SafeAreaView, TouchableOpacity,AsyncStorage
} from "react-native";
import {withNavigation} from 'react-navigation'
import i18n from 'i18next';
import { translate } from 'react-i18next';
import NavigationService from './NavigationService';
import AppIntroScreen from './AppIntroScreen'
class ChooseLanguage extends Component {
    state = {
        isArabic: false,
        isEnglish: false,
        switchLang: true,
        languageSet:false
    }
    async onChangeLang(lang) {
        i18n.changeLanguage(lang);
        try {
            await AsyncStorage.setItem('@APP:languageCode', lang);
        } catch (error) {
            console.log(` Hi Errorrrr : ${error}`);
        }
        console.log(i18n.dir());
        this.setState(state => ({
            switchLang: !state.switchLang,
        }));
    }
    render() {
        const {t,navigation} = this.props;
        console.log(navigation)
        return (
           (this.state.switchLang ? <SafeAreaView style={styles.container}>
                <Image source={require('../assets/lang.png')} />
                <Text style={{ fontSize: 25, color: '#FF5252', marginTop: 20, fontFamily: 'Hanken-Book' }}>Choose Language</Text>
                <View style={{ flexDirection: 'row', justifyContent: 'space-evenly' }}>
                    <TouchableOpacity onPress={() => this.setState({ isEnglish: true, isArabic: false })} style={{ marginVertical: 20, marginHorizontal: 20, padding: 10, borderBottomColor: this.state.isEnglish ? '#a8a8a8' : '#ffffff', borderBottomWidth: this.state.isEnglish ? 1 : 0 }}>
                        <Text style={{color:this.state.isEnglish?'#000000':'#A8A8A8'}}>English</Text>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={() => this.setState({ isEnglish: false, isArabic: true })} style={{ marginVertical: 20, marginHorizontal: 20, padding: 10,borderBottomColor: this.state.isArabic ? '#a8a8a8' : '#ffffff', borderBottomWidth: this.state.isArabic ? 1 : 0 }}>
                        <Text style={{color:this.state.isArabic?'#000000':'#A8A8A8'}}>Arabic</Text>
                    </TouchableOpacity>
                </View>
                <TouchableOpacity onPress={() =>
                {
                    if(this.state.isArabic){
                        this.onChangeLang('ar');
                        this.props.navigation.navigate('AppIntroScreen');
                    }else if(this.state.isEnglish){
                        this.onChangeLang('en');
this.props.navigation.navigate('AppIntroScreen'); 
                        }else{
                            alert('Please Choose a language')
                        }
                    }
                    } style={{ backgroundColor: '#FF5252', alignSelf: 'center', padding: 10, width: '40%', marginTop: 15,borderRadius:5 }}>
                            <Text style={{ color: '#FFF', fontSize: 18, fontWeight: '100', textAlign: 'center', fontFamily: 'Hanken-Book' }}>Let's Start</Text>
                        </TouchableOpacity>
                    <View style={{
                        position: 'absolute',
                        bottom: 0,
                        right: 1,
                        left: 1,
                        height: 50,
                        justifyContent: 'center', alignItems: 'center'
                    }}>
                        <Image source={require('../assets/l1.png')} style={{ width: 120, height: 25 }} />
                    </View>
                </SafeAreaView>:<AppIntroScreen />)
            );
        }
    }
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            alignItems: 'center',
            justifyContent: 'center',
            bottom: 20
        }
    });
export default translate(['chooselanguage'], { wait: true })(ChooseLanguage);

即使我在 StackNavigator 中注册了所有屏幕,这里是 App.js 的代码

    const TabNav = createBottomTabNavigator({
        HomeScreen: {
            screen: HomeScreen,
        },
        Categories: {
            screen: Categories,
        },
        Search: {
            screen: Search,
        },
        Settings: {
            screen: Settings,
        },
    }, {
            tabBarOptions: {
                activeTintColor: '#ff5252',
                inactiveTintColor: 'grey',
                style: {
                    backgroundColor: 'white',
                    borderTopWidth: 0,
                    shadowOffset: { width: 5, height: 3 },
                    shadowColor: 'black',
                    shadowOpacity: 0.5,
                    elevation: 5
                }
            }
        })

const StacksOverTabs = createStackNavigator({
    Root: {
        screen: TabNav,
    },
    ChooseLanguage:{
        screen: ChooseLanguage,
        navigationOptions:{

        }
    },
    ListingPerCategory: {
        screen: ListingPerCategory,
        navigationOptions: {
            // title: 'Notifications',
        },
    },
    ListingInformation: {
        screen: ListingInformation,
        navigationOptions: {}
    },
    SubscribeScreen: {
        screen: SubscribeScreen,
        navigationOptions: {}
    },
    AppIntroScreen: {
        screen: AppIntroScreen,
        navigationOptions: {}
    },
    OnboardingScreens: {
        screen: OnboardingScreens,
        navigationOptions: {}
    },

    ListingDetail: {
        screen: ListingDetail,
        navigationOptions: {}
    },
    Contact: {
        screen: ContactScreen,
        navigationOptions: {}
    },

}, {
        headerMode: 'none',
        navigationOptions: {
            headerVisible: false,
        }

    });

const WrappedStack = ({ t,navigation }) => {
    return <StacksOverTabs screenProps={{ t,navigation}} />;
};

const ReloadAppOnLanguageChange = translate('common', {
    bindI18n: 'languageChanged',
    bindStore: false,
})(WrappedStack);


class App extends React.Component {
    state = { notification: {}, timePassed: false }

    componentDidMount() {
        OneSignal.init('99471d55-8e89-49ef-a70f-47661c9f952b', { kOSSettingsKeyAutoPrompt: true })
        OneSignal.addEventListener('received', this.onReceived);
        OneSignal.addEventListener('opened', this.onOpened);
        OneSignal.addEventListener('ids', this.onIds);
    }
    async retrieveItem(key) {
        try {
          const retrievedItem =  await AsyncStorage.getItem(key);
          const item = JSON.parse(retrievedItem);

          return item;
        } catch (error) {
          console.log("error");
        }
        return
      }

    componentWillUnmount() {
        OneSignal.removeEventListener('received', this.onReceived);
        OneSignal.removeEventListener('opened', this.onOpened);
        OneSignal.removeEventListener('ids', this.onIds);
    }

    onReceived(notification) {
        console.log("Notification received: ", notification);
    }

    onOpened(openResult) {
        console.log('Message: ', openResult.notification.payload.body);
        console.log('Data: ', openResult.notification.payload.additionalData);
        console.log('isActive: ', openResult.notification.isAppInFocus);
        console.log('openResult: ', openResult);
    }

    onIds(device) {
        console.log('Device info: ', device);
    }
    render() {
        this.retrieveItem('appLaunched').then((goals) => {
            console.log(goals)
            }).catch((error) => {
            //this callback is executed when your Promise is rejected
            console.log('Promise is rejected with error: ' + error);
            }); 
        return <ReloadAppOnLanguageChange />
    }

}

export default App;

标签: react-nativereact-navigation

解决方案


您可以通过组合withNavigation HOC(在 v1 中不可用)来访问navigation任何组件(深度嵌套)中的 prop 。当您无法将导航道具直接传递到组件中时,它很有用,或者在嵌套深度嵌套的孩子的情况下不想传递它。

import React from 'react';
import { Button } from 'react-native';
import { withNavigation } from 'react-navigation';

class MyBackButton extends React.Component {
  render() {
    return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />;
  }
}

// withNavigation returns a component that wraps MyBackButton and passes in the
// navigation prop
export default withNavigation(MyBackButton);

推荐阅读