Adam
Adam

Reputation: 350

React navigation passing function to a stack navigator and then a header component

I have an expo react native app with react-navigation v3.

I am passing a signOut function from my main App to a header component of one of my stack navigators. I want to pass this header once so I don't want to add it to the navigationOptions for every screen.

I'm having trouble accessing the props in my MainStackNavigator and passing the function down to my component.

Main App

 render () {
        return (
            <View style={styles.container}>
                <AppNavigator screenProps={{ signOut: this.signOut }}/>
            </View>
        );
    }

AppNavigator

export default createAppContainer(
    createSwitchNavigator({
        // You could add another route here for authentication.
        // Read more at https://reactnavigation.org/docs/en/auth-flow.html
        Main: MainStackNavigator,
    },
    {
        initialRouteName: 'Main'
    })
);

MainStackNavigator

export default createStackNavigator({
    Home: { 
        screen: HomeScreen, 
    }
},{
    initialRouteName: 'Home',
    defaultNavigationOptions : {
        headerTitle: <LogoTitle signOut={this.screenProps.signOut}/>,
        headerMode: 'screen',
    }
});

So when I am passing in the component LogoTitle, how do I access the screenProps at this point?

Upvotes: 0

Views: 1420

Answers (2)

windmaomao
windmaomao

Reputation: 7671

Passing something around in react is very typical task, before showing you the answer, we need to understand react doesn't like things injected out of nowhere, by default, you need to pass it to the children. Most of time, this means if you have a problem, you actually have a problem of parent-children relationship, either going up or down.

So in order to solve your problem in a bit generic way, you could consider passing a function that could change your screenProps, not screenProps, unless screenProps is always read only from the children point of view.

There's quite a bit way to achieve that. I'm only showing you one way via hooks

  const [props, setProps] = useState({ default props })
  return (
    <ChildrenComp onChange={setProps} />
  )

From now one, your children can always change props whenever they want via onChange.

And now we're back to the old things, which is passing props to children where you need them.

I'm not a fan of redux for simple problems, if you know your parent and your children, you should architect your code to facilliate that. If you really have to, you can go useContext, and really if you have no other choice, you can go redux. Don't use redux at the very beginning, it's not helpful for entry level programming especially when you are not 100% sure what is a prop in react.

Upvotes: 2

thecodrr
thecodrr

Reputation: 275

I don't think you can access the screenProps in a createStackNavigator function. There's actually no point in passing it as screenProps because screenProps are accessible in screens/views not Navigators. Moreover, there's no screenProps prop in AppNavigator.

The correct way to do this would be through a signOut function that's defined in an auth.js file and accessible from everywhere. If you want to react to user's sign out then use redux and update the state and react to that update instead.

Upvotes: 2

Related Questions