title: React-Navigation passing functions to screenProps
body: <p>I am creating an app using React Native, Expo and React Navigation, and I don't know the correct method for passing props and functions around.</p>
  
  <p>I have copied the Expo method for navigators that I will build on, but right now I just have App.js calling the following 
  AppNavigator -> MainSwitchNavigator -> HomeScreen</p>
  
  <p>I have then wrapped the main exported App that Expo expects with the Amazon AWS Amplify HOC withAuthenticator. Now I can log in to my app and show hello world securely using Amazon's cognito service.</p>
  
  <p>If I want to log out I can use the signout function bellow that I currently have on the props of App.</p>
  
  <pre><code>class App extends React.Component {
  
    constructor(props) {
      super(props);
      this.signOut = this.signOut.bind(this);
    }
  
    signOut() {
      Auth.signOut().then(() =&gt; {
        this.props.onStateChange('signedOut', null);
        console.log("signed out");
      }).catch(e =&gt; {
        console.log(e);
      });
    }
  
    render () {
      return (
          &lt;View style={styles.container}&gt;
            &lt;AppNavigator screenProps={{
              signOut: () =&gt; {this.signOut}
              }}/&gt;
          &lt;/View&gt;
      );
    }
  }
  
  export default withAuthenticator(App)
  </code></pre>
  
  <p>For now I just want to pass this function down to my Home Screen so I can add a button and log out. </p>
  
  <p><strong>AppNavigator</strong></p>
  
  <pre><code>export default createAppContainer(
    createSwitchNavigator({
      // You could add another route here for authentication.
      // Read more at https://reactnavigation.org/docs/en/auth-flow.html
      Main: { screen: MainSwitchNavigator, params: { signOut: this.props.screenProps.signOut } },
    },
    {
      initialRouteName: 'Main'
    })
  );
  
  </code></pre>
  
  <p><strong>MainSwitchNavigator</strong></p>
  
  <pre><code>export default createSwitchNavigator({
      // Home: { screen: HomeScreen }
      Home: { screen: HomeScreen, params: { signOut: this.props.navigation.params.signOut } }
  },{
      initialRouteName: 'Home'
  });
  </code></pre>
  
  <p><strong>HomeScreen</strong></p>
  
  <pre><code>class HomeScreen extends Component {
    render () {
    return (
      &lt;View&gt;
        &lt;Text&gt;Main App Here&lt;/Text&gt;
        &lt;Button 
          onPress={this.props.navigation.params.signOut()} 
          title="Sign Out" 
        /&gt;
      &lt;/View&gt;
    )};
  }
  
  export default HomeScreen;
  </code></pre>
  
  <p>At the moment I get the error </p>
  
  <pre><code>undefined is not an object (evaluating 'this.props.navigation')
  &lt;unknown&gt;
  MainSwitchNavigator.js
  8:62
  </code></pre>
  
  <p>Which puts its at the point I'm trying to read the props passed in to MainSwitchNavigator.</p>
  
  <p>So my question is, what is good practice on sharing functions and state with screens below the main App and how do I pass the signOut function down to the rest of my components?</p>
  
  <p>=======================================================================</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>I have since worked out how to use screenProps correctly for variables but not for functions. screenProps is passed down through navigators automatically to the screen. So I only have to pass it to the AppNavigator component once and I can access it in HomeScreen. However any functions are not passed down.</p>
  
  <p>E.g for variables, if I modify App.js to pass text to the variable signOut and pass that to screenProps</p>
  
  <pre><code>class App extends React.Component {
  
    constructor(props) {
      super(props);
      this.signOut = this.signOut.bind(this);
    }
  
    signOut() {
      Auth.signOut().then(() =&gt; {
        this.props.onStateChange('signedOut', null);
        console.log("signed out");
      }).catch(e =&gt; {
        console.log(e);
      });
    }
  
    render () {
      return (
          &lt;View style={styles.container}&gt;
            &lt;AppNavigator screenProps={{signOut: "some text"}}/&gt;
          &lt;/View&gt;
      );
    }
  }
  </code></pre>
  
  <p>HomeScreen will then show this as part of the this.props object.</p>
  
  <pre><code>class HomeScreen extends Component {
    render () {
    return (
      &lt;View&gt;
        &lt;Text&gt;Main App Here&lt;/Text&gt;
        &lt;Button 
          onPress={console.log(JSON.stringify(this.props))} 
          //  onPress={alert(this.props.screenProps.var3)} 
          title="Sign Out" 
        /&gt;
      &lt;/View&gt;
    )};
  }
  
  export default HomeScreen;
  </code></pre>
  
  <p>However if I pass a function to AppNavigator instead and do this</p>
  
  <pre><code>&lt;AppNavigator screenProps={{signOut: () =&gt; {this.signOut}}}/&gt;
  </code></pre>
  
  <p>screenProps does not get set and I can't access the function signOut.
  The only thing I can get to work is this</p>
  
  <pre><code>&lt;AppNavigator screenProps={this.signOut}/&gt;
  </code></pre>
  
  <p>But what I need is to create a property of screenProps and pass this down. Any thoughts?</p>