xiaolingxiao
xiaolingxiao

Reputation: 4895

React Native pass `props` through navigation container built by `createStackNavigator`

I have a react-native app with top level App.js that is:

import { createStackNavigator } from 'react-navigation';

class App extends Component {
  render() { 
    return <AppStack {..this.props} /> 
  }
}

export withAuth(App)

Where the higher order component withAuth adds user and authenticating props to App:

const withAuth = (Component) =>
  class WithAuth extends React.Component {
    constructor(props) {
      super(props)
      this.state = {
        authenticating: true,
        user: false
      }
    }

    componentDidMount() {
      // authenticating logic ...
      firebase.auth().onAuthStateChanged(user => {
        if (user)
          this.setState({
            authenticating: false,
            user: user
          })
        else
          this.setState({
            authenticating: false
          })
      })
    }

    render() {
      return (<Component user={this.state.user} authenticating={this.state.authenticating} {...this.props} />)
    }
  }

And the AppStack is:

const AppStack = createStackNavigator( 
    { AppContainer, Profile }, 
    { initialRouteName : 'AppContainer' }
)

Note there is no code passing the props that was passed down from class App down to AppContainer and Profile.

Consequentially the user and authenticating props inside AppContainer is undefined.

class AppContainer extends Component {
  //  this.props.user is false and this.props.authenticating is true
  componentDidMount() {
    console.log(`Debug Did mount with user: ${this.props.user}`, this.props.authenticating)
  }

  render() {
    // if I `export withAuth(AppContainer)`, then this prints the user information. but not if I log inside `componentDidMount`
    console.log(`Debug loaded with user: ${this.props.user}`, this.props.authenticating)
    return <Text>'hello world'</Text>
  }
}

export default AppContainer

I could wrap AppContainer inside withAuth and do export default withAuth(AppContainer), but then AppContainer cannot read this.props.user property in componentDidMount, only in render() { ... }.

Ideally I would like to pass down the user and authenticating property from AppStack, how would I do so?

Note: for now I would like to not use redux if possible. This is a simple app.

Upvotes: 3

Views: 6064

Answers (1)

tuan.tran
tuan.tran

Reputation: 1881

You can pass props from your high order component to child screen through screenProps. Example:

const withTest = Component => (
  class WithTest extends React.Component {
    render() {
      return (<Component screenProps={{ user: "abc" }} />);
    }
  });

Check Navigator Props for more detail.

Upvotes: 5

Related Questions