0

Simple question: I am trying to navigate from HomeScreen.js to MessageScreen once pressing the HomeScreen.js header's image.

However, when I press the image an error pops up:

TypeError: navigation.navigate is not a function (In 'navigation-navigate("MessageScreen")', 'navigation.navigate' is undefined)

What is the problem with the navigation? This is the main code from App.js

const HomeStack = createStackNavigator({
      HomeScreen: {
        screen: HomeScreen,
        navigationOptions: (navigation) => ({
            headerShown: true,
            title:'As minhas viagens',
            headerTintColor:'black',
            headerRight: ()=>  
                <TouchableOpacity onPress={() => navigation.navigate("MessageScreen")}>
                    <Image 
                    source={require("./assets/message.png")} 
                    style={{width: 40,height: 40, borderRadius: 40 / 2}}/>
                </TouchableOpacity>
        })
      },
      MessageScreen: {
        screen: MessageScreen,
        navigationOptions: () => ({
          headerShown: true
        })
      }
    });
Tiago 2.0
  • 141
  • 3
  • 12

3 Answers3

1

You shoud pass props to your function otherwise it has no way of knowing what this 'navigation' is , try something like

headerRight: ({navigation})=>  
                <TouchableOpacity 
                    onPress={() => navigation.navigate("MessageScreen")}>
                        <Image 
                        source={require("./assets/message.png")} 
                        style={{width: 40,height: 40, borderRadius: 40 / 2}}/>
                </TouchableOpacity>

or this?

headerRight: (props)=>  
                <TouchableOpacity 
                    onPress={() => props.navigation.navigate("MessageScreen")}>
                        <Image 
                        source={require("./assets/message.png")} 
                        style={{width: 40,height: 40, borderRadius: 40 / 2}}/>
                </TouchableOpacity>
Andris Laduzans
  • 408
  • 4
  • 14
  • I have tried both methods but I get 'TypeError: undefined is not an object (evaluating 'props.navigation.navigate') – Tiago 2.0 Jul 03 '20 at 09:58
  • sorry then. Well you could try using useNavigation hook. But it doesnt look like you are using RN navigation 5 – Andris Laduzans Jul 03 '20 at 10:06
  • I am using RN 4.3. I am kind of new to react native, so why should I use RN 5 instead? – Tiago 2.0 Jul 03 '20 at 10:08
  • 5 is new version of react navigation. It is much simpler to use and adds a ton of features which would definitely help you. for example this 'useNavigation' hook which you can just pass into any React component and just use navigation without any props passing. BUT rewriting whole navigation just to solve this problem is probaly overkill. – Andris Laduzans Jul 03 '20 at 10:11
  • Well ye, it was what I was thinking now. I would have to start almost everything over with my app just to solve this little issue :\, It's just not worth it at the moment. – Tiago 2.0 Jul 03 '20 at 10:15
  • Its not like you have to ovverwite all of your app. My company, we did the same thing, and we had quite large codebase allready. You dont have to delete your react components or anything. it took me ~2 days to rewrite our app and push new release. It was definitely worth it in long run. – Andris Laduzans Jul 03 '20 at 10:19
1

Try this:

const HomeStack = createStackNavigator({
      HomeScreen: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => {
          return {
            headerShown: true,
            title:'As minhas viagens',
            headerTintColor:'black',
            headerRight: () =>  
                <TouchableOpacity onPress={() => navigation.navigate("MessageScreen")}>
                    <Image 
                    source={require("./assets/message.png")} 
                    style={{width: 40,height: 40, borderRadius: 40 / 2}}/>
                </TouchableOpacity>
          }
        })
      },
      MessageScreen: {
        screen: MessageScreen,
        navigationOptions: () => ({
          headerShown: true
        })
      }
    });
giotskhada
  • 2,326
  • 1
  • 11
  • 18
  • Thanks, it worked! I would really like to now though, why do I need to code "return" as a children of navigation options? – Tiago 2.0 Jul 03 '20 at 10:43
  • The braces after `() => {}` are read as a function block and not as an object block. So, the compiler thinks you just wrote down some properties inside a block instead of returning an actual object. – giotskhada Jul 03 '20 at 10:45
0

Have you tried to use:

this.props.navigation.navigate("MessageScreen")

or

props.navigation.navigate("MessageScreen") ?

yesIamFaded
  • 1,970
  • 2
  • 20
  • 45