André Abboud
André Abboud

Reputation: 2030

this.props.navigation.navigate does not work in screen

In my app I have a choose language screen which I have registered in the stackNavigator but I cannot use this.props.navigation.navigate in it this 'choose language screen' appears on app first launch

this is 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 is ChooseLanguage Screen so when pressing the touchable opacity I am calling this.props.navigation.navigate('AppIntroScreen') but it is not working it is giving me this error: undefined is not an object (evaluating _this2.props.navigation.navigate)

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);

even though I am registering all my screens in the StackNavigator here is the code of 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;

Upvotes: 0

Views: 5413

Answers (1)

Shivam
Shivam

Reputation: 3131

You can access the navigation prop in any component(deeply nested) by composing withNavigation HOC (not available in v1). It's useful when you cannot pass the navigation prop into the component directly, or don't want to pass it in case of a deeply nested child.

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);

Upvotes: 1

Related Questions