Robin Manoli
Robin Manoli

Reputation: 2222

How to access navigation outside main component?

I've been working with the default tabs project created with create-react-native-app.

So I created my own screen where this.props.navigation is accessible in the main (export default class) component. It works fine to do navigate('Search') from the button titled 'nav default'.

However, after many tries, I couldn't navigate from either the button in the headerRight or in my custom component MyComponent.

How do I change my alerts to instead do navigate('Search') like the main component?

import React from 'react';
import { Button, Dimensions, ScrollView, StyleSheet, Text, View } from 'react-native';

class MyComponent extends React.Component {
    // i wish i could navigate from here
    render() {
        //const { navigate } = this.props.navigation; // this causes TypeError undefined is not an object (evaluating this.props.navigation.navigate)
        return (
        <View>
            <Button title="nav from component" onPress={() => alert('This should navigate, not alert')} color="red" />
        </View>
        );
    }
}

export default class MyScreen extends React.Component {
  // i wish i could navigate from here too
  static navigationOptions = {
    title: 'Test',
    headerRight: (
        //<Button onPress={() =>navigate('Search')} /> // how do I achieve this?
        <Button title="nav from header" onPress={() => alert('This should navigate, not alert')} />
    ),
  };

  render() {
    const { navigate } = this.props.navigation;
    return (
      <ScrollView style={styles.container}>
        <Button onPress={() =>navigate('Search')} title="nav default" />
        <MyComponent />
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 15,
    backgroundColor: '#fff',
  },
});

Upvotes: 1

Views: 930

Answers (1)

Filipe
Filipe

Reputation: 884

There are two different problems. First, navigation is only passed as a prop to the components that are navigation screens. So, to access it from other components, such as your MyComponent, you have to pass it through props <MyComponent navigation={navigation} /> and then you can use this.props.navigation.navigate inside it. You can also use the withNavigation higher order component, but in that case the first approach is better. The other problem is, if you want to access the navigation prop in navigationOptions, you should define it as a function, and not as an object. The implementation would be something like this:

static navigationOptions = ({ navigation }) => ({
  title: 'Test',
  headerRight: (
    <Button onPress={() =>navigation.navigate('Search')} />
  ),
});

Upvotes: 1

Related Questions