Kureev / react-native-side-menu

Side menu component for React Native
MIT License
2.21k stars 434 forks source link

Change Screen when click in menu item #325

Open ludiaz opened 6 years ago

ludiaz commented 6 years ago

App.js

import React, { Component } from 'react';
import { AppRegistry, StyleSheet, TouchableOpacity, Image } from 'react-native';
import {Screens} from './config/router';
import Menu from './screens/Menu';
import SideMenu from 'react-native-side-menu';

const menuHamburger = require('./assets/menu_hamburger.png');

const styles = StyleSheet.create({
  menuHamburger: {
    position: 'absolute',
    top: 2,
    padding: 10,
  },
}); 

export default class App extends React.Component {

  constructor(props){
    super(props);

    this.toggle = this.toggle.bind(this);

    this.state = {
      isOpen: false,
      selectedItem: 'Screen1'
    };
  }

  toggle() {
    this.setState({
      isOpen: !this.state.isOpen,
    });
  }

  updateMenuState(isOpen) {
    this.setState({ isOpen });
  }  

  onMenuItemSelected = item => {

    console.log(item)

    this.setState({
      isOpen: false,
      selectedItem: item,
    });
  }

  render(){

    const menu = <Menu onItemSelected={this.onMenuItemSelected} navigator={navigator}/>;

    return (
      <SideMenu
        menu={menu}
        isOpen={this.state.isOpen}
        onChange={isOpen => this.updateMenuState(isOpen)}>
        <Screens />
        <TouchableOpacity onPress={this.toggle} style={styles.menuHamburger}>
          <Image source={menuHamburger} style={{ width: 32, height: 32 }} />
        </TouchableOpacity>
      </SideMenu>
    );
  }
}

router.js

import React from 'react';
import { StackNavigator } from 'react-navigation';
import { StyleSheet } from 'react-native';

import Screen1 from '../screens/Screen1';
import Screen2 from '../screens/Screen2';
import Screen3 from '../screens/Screen3';
import Screen4 from '../screens/Screen4';

const styles = StyleSheet.create({
    titleMenu: {
      left: 50
    },
}); 

export const Screens = StackNavigator(

    {
        Screen1 :{
            screen: Screen1,
            navigationOptions: {
                title: 'Screen 1',
                headerTitleStyle: styles.titleMenu,
                headerLeft: null
            }
        },

        Screen 2:{
            screen: Screen2,
            navigationOptions: ({navigation}) => ({
                title: 'Screen 2',
                headerTitleStyle: styles.titleMenu,
                headerLeft: null          
            }),        
        },

        Screen3:{
            screen: Screen3,
            navigationOptions: ({navigation}) => ({
                title: 'Screen 3',
                headerTitleStyle: styles.titleMenu,
                headerLeft: null
            })
        },

        Screen4:{
            screen: Screen4,
            navigationOptions: ({navigation}) => ({
                title: 'Screen 4',
                headerTitleStyle: styles.titleMenu,
                headerLeft: null
            })
        },
    },
    {
        initialRouteName: 'Screen1',
        headerMode:'float',        
    }
);

Menu.js

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import { Dimensions, StyleSheet, ScrollView, View, Image,Text } from 'react-native';

const window = Dimensions.get('window');

const styles = StyleSheet.create({
  menu: {
    flex: 1,
    width: window.width,
    height: window.height,
    backgroundColor: 'gray',
    padding: 20,
  },
  avatarContainer: {
    marginBottom: 20,
    marginTop: 20,
  },
  avatar: {
    width: 48,
    height: 48,
    borderRadius: 24,
    flex: 1,
  },
  name: {
    position: 'absolute',
    left: 70,
    top: 20,
  },
  item: {
    fontSize: 20,
    fontWeight: 'bold',
    paddingTop: 5,
    color: 'white'
  },
});

export default function Menu({ onItemSelected }) {
  return (
    <ScrollView scrollsToTop={false} style={styles.menu}>
      <Text onPress={() => onItemSelected('Screen1')} style={styles.item} >Screen 1</Text>
      <Text onPress={() => onItemSelected('Screen2')} style={styles.item}>Screen 2</Text>
      <Text onPress={() => onItemSelected('Screen3')} style={styles.item}>Screen 3</Text>
      <Text onPress={() => onItemSelected('Screen4')} style={styles.item}>Screen 4</Text>
    </ScrollView>
  );
}

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

The code works fine. But, the principal question now is:

How i change the screen when i click in menu item. On App.js, the code "onMenuItemSelected" receive the item parameter correctly. but, i try to use something like "const { navigate } = this.props.navigation;" at constructor (App.js) but, raise a excepction.

I would be very happy if someone help-me!

iSachdeva commented 6 years ago

@ludiaz I also need support for same implementation as mentioned by you. Is there any solution so far? Appreciate any help!!!

daveteu commented 6 years ago

@ludiaz that's a react navigator problem since you cannot use "this"

RuthenicEye commented 6 years ago

@daveteu if one cannot use 'this' what is the solution. any help would be appreciated

xzessmedia commented 5 years ago

if i understood your problem correctly,

you can add a state changing function in your parent / main component and then pass it as a prop to the child. react re-renders when state changes...

read this https://stackoverflow.com/questions/35537229/how-to-update-parents-state-in-react