Roland Jegorov
Roland Jegorov

Reputation: 819

Proper navigation in react-native

Having a bit of a struggle with understanding how to properly implement navigation in RN. The following code should be enough to see the current situation.

HeaderConnected is a component with a menu button which has a custom navigate prop to be able to open the Drawer menu (However, I believe this is not a proper way to pass navigate).

– Problem
HeaderConnected is in Main.js

– Expected
HeaderConnected to be above Navigator

App.js

// ...
import { DrawerNavigator } from "react-navigation";

export const Navigator = DrawerNavigator({
    Main: { screen: Main },
    Edit: { screen: EditScreen },
});
export default class App extends React.Component {
    render() {
        return (
            <Provider store={createStore(reducer)}>
                <Navigator />
            </Provider>
        );
    }
}

Main.js

export class Main extends React.PureComponent {
    static navigationOptions = {
        drawerLabel: "Main",
    };
    render() {
        return (
            <View style={styles.container}>
                <HeaderConnected
                    navigate={this.props.navigation.navigate}
                /> // <--- This should be moved above <Navigator /> in App.js
                <PostsConnected />
            </View>
        );
    }
}

Of course, you could create another wrapper to hold both Navigator and HeaderConnected which you would then pass to Provider. However, this didn't work for me.

After reading react-navigator docs it seems there are several ways to handle this, alas not sure what would be the best/optimal way.

Upvotes: 1

Views: 534

Answers (1)

Guilherme Cronemberger
Guilherme Cronemberger

Reputation: 814

I had this problem in a recent project and worked it around by building a wrapper as you said, try using this code:

    const mapNavigationStateParamsToProps = (SomeComponent) => {
      return class extends Component {
        static navigationOptions = SomeComponent.navigationOptions; // better use hoist-non-react-statics
        render() {
          const { navigation: { state: { params } } } = this.props
          return (
             <View style={{ flex: 1 }}>
               <HeaderConnected
                    navigate={this.props.navigation.navigate}
                />
               <SomeComponent {...params} {...this.props} />

             </View>
      )
    }
  }
}

then on your Navigator:

export const Navigator = DrawerNavigator({
    Main: { screen: mapNavigationStateParamsToProps(Main) },
    Edit: { screen: mapNavigationStateParamsToProps(EditScreen) },
});

I'm not sure if it is the best/optimal way, but it works for me.

Upvotes: 2

Related Questions