1

Im having issue using react-native-side-menu to navigate between different scene.Mainly because my NavigatorIOS is inside the SideMenu, so I believe the props.navigator doesn't exist until NavigatorIOS is rendered?

the main code:

class HomeScene extends Component{
  static title = 'Home';

  constructor(props){
    super(props);
    this.state={
      title:'Home'
    };
  }

  render(){
    return (
      <View style={styles.defaultContainer}>
          <Text style={styles.defaultText}>
              You are on the Home Page
          </Text>
          <View style={styles.group}>
            {this._renderRow("To another page", () => {
              this.props.navigator.push({
                title: Page.title,
                component: Page,
                passProps: {depth: this.props.depth ? this.props.depth + 1 : 1},
                onLeftButtonPress: () => this.props.navigator.pop(),
              });
            })}
          </View>
      </View>
    );
  }

  _renderRow = (title: string, onPress: Function) => {
    return (
      <View>
        <TouchableHighlight onPress={onPress}>
          <View style={styles.row}>
            <Text style={styles.rowText}>
              {title}
            </Text>
          </View>
        </TouchableHighlight>
      </View>
    );
  };
}

class Menu extends Component{
  constructor(props){
    super(props);
  }

  static propTypes={
    onItemSelected: React.PropTypes.func.isRequired,
  };

  _renderRow = (title: string, onPress: Function) => {
    return (
      <View>
        <TouchableHighlight onPress={onPress}>
          <View style={styles.row}>
            <Text style={styles.rowText}>
              {title}
            </Text>
          </View>
        </TouchableHighlight>
      </View>
    );
  };

  render(){
    return(
      <ScrollView scrollsToTop={false} style={styles.sideMenuBar}>
        {this._renderRow("Home", function(){
          this.props.navigator.replace({
            title: 'Home',
            component: HomeScene,
            passProps: {depth: this.props.depth ? this.props.depth + 1 : 1},
            onLeftButtonPress: () => this.props.navigator.pop(),
          });
        })}

        {this._renderRow("Page", function(){
          this.props.navigator.replace({
            title: 'Page',
            component: Page,
            passProps: {depth: this.props.depth ? this.props.depth + 1 : 1},
            onLeftButtonPress: () => this.props.navigator.pop(),
          });
        })}
         </ScrollView>
        )
      }
}


class App extends Component {
  render() {
      const menu = <Menu onItemSelected={this.onMenuItemSelected} navigator={this.props.navigator}/>; <--- will be undefined
      return (
              <SideMenu
                menu={menu}
                isOpen={this.state.isMenuSideBarOpen}
                onChange={(isOpen)=>{this.updateMenuState(isOpen)}}
              >
               <StatusBar
                backgroundColor="blue"
                barStyle="light-content"
               />
               <NavigatorIOS
                initialRoute={{
                  component: HomeScene,
                  title: this.state.selectedItem,
                  leftButtonIcon: this.state.menuIcon,
                  onLeftButtonPress: ()=>{
                    this.toggle();
                  }
                }}
                style={{flex: 1}}
                tintColor="#FFFFFF"
                titleTextColor="#FFFFFF"
                barTintColor='#000099'
              >
              </NavigatorIOS>
             </SideMenu>
        );
     }
  }
}

As you see, I used same code for handling navigation in menu and home scene, but on home page rendered by the NavigatorIOS will have the props.navigator property, on the other hand, if I click the home button on Menu, it will give me an error says that props.navigator is undefined.

So how should I fix this? And what is the problem with my code? I'm a fresh learner of react native, still bit confusing about how should I wrap different component in the correct way.

To have a better view, here is the source file

XYZ_Allen
  • 253
  • 2
  • 3
  • 15

1 Answers1

0

Probably the easiest way would be to add this.props.navigator to the route. So like:

{this._renderRow("To another page", () => {
              this.props.navigator.push({
                navigator: this.props.navigator
                title: Page.title,
                component: Page,
                passProps: {
                    depth: this.props.depth ? this.props.depth + 1 : 
                        1},
                    onLeftButtonPress: () => 
                        this.props.route.navigator.pop()
              });
            })}

You should then be able to access the navigator from the route using this.props.route.navigator. I am assuming App is like your root component and is rendered before the rest.

I'm not as familiar with NavigatorIOS but if there's a way to override the renderScene function, that would be a better way - just specify the navigator prop to the child rendered by that function.

SoZettaSho
  • 950
  • 11
  • 20