Kureev / react-native-side-menu

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

Referring to only 1 SideMenu Throughout Code #155

Closed robtg4 closed 8 years ago

robtg4 commented 8 years ago

I seem to be having some difficulty with requiring only one side menu per app instead of having the same side menu implemented on every page that the menu can navigate to - much like keeping one tabbar per app where you can navigate to the different tab pages

right now, my home.js component - the first page to have the side menu, looks like this (i took the toggle implementation you used to make the menu work with MenuButton):

var React = require('react-native');
var {
    View, 
    Image,
    StyleSheet,
    Text, 
    ListView, 
    TouchableHighlight, 
    AsyncStorage, 
} = React;

//additional libraries
var Parse = require('parse/react-native');
var EventEmitter = require('EventEmitter');
var Spinner = require('react-native-spinkit');
var SideMenu = require('react-native-side-menu');
var Subscribable = require('Subscribable');

//dynamic component references + libraries 
var ArticlePreview = require('./exp_base_components/article-preview');
var Api = require('../utils/api');
var FeedStore = require('../stores/feed-store');
var ArticleDetails = require('./exp_base_components/article-details');
var Menu = require('./menu');
var MenuButton = require('../common/menuButton');

//dimensions
var Dimensions = require('Dimensions');
var window = Dimensions.get('window');

module.exports = React.createClass({ 
    //mixins are for menu functionality taken from 
    //here: https://github.com/mcnamee/react-native-starter-app
    mixins: [Subscribable.Mixin],
    componentWillMount: function() {
        this.eventEmitter = new EventEmitter();
        Parse.User.currentAsync()
            .then((user) => { this.setState({user: user}); })
    },  
    //on first login (and all new logins)
    //need to pull onboarding keywords that indicate user interests
    //so that we can pull the appropiate feeds 
    componentDidMount: function() {
        //console.log(this.state.user);
        var personalFeed = null; 
        var Onboarding = Parse.Object.extend("Onboarding");
        var query = new Parse.Query(Onboarding);
        query.equalTo("userObjectId", Parse.User.current());
        var that = this;
        query.find({
          success: function(result) {
            console.log("Successfully retrieved " + result.length + " users!");
            var object = result[0];
            console.log(object.id);
            // Do something with the returned Parse.Object values
            console.log(object.get('interests'));
            that.fetchData(object.get('interests'));
          },
          error: function(error) {
            console.log("Error: " + error.code + " " + error.message);
          }
        });

    },
    //states of this components 
    getInitialState: function() {
        return {
            user: null, 
            personalFeed: null, 
            touchToClose: true,
            disableGestures: false,
            isLoaded: false, 
            dataSource: new ListView.DataSource({
               rowHasChanged: (row1, row2) => row1 !== row2,
            }), 
        }
    },
    //part of menu button functionality 
    navigate: function(title, link) {
      this.refs.rootSidebarMenu.closeMenu();

      this.refs.rootNavigator.replace({
        title: title,
        component: link,
      });
    },
    //gettign data for rss feed based on user interests 
    fetchData: function(personalFeed) {
        var that = this; 
        FeedStore.getArticles(personalFeed)
            .then((data) => {
                var entries = data; 
                that.setState({
                    dataSource : that.state.dataSource.cloneWithRows(entries),
                    isLoaded   : true, 
                });
            }).done();
    }, 
    //rendering component 
    render: function() {

        if (!this.state.isLoaded) {
            return this.renderLoadingView();
        }
        return <SideMenu 
                    menu={<Menu events={this.eventEmitter} navigate={this.navigate} />}
                    touchToClose={this.state.touchToClose}
                    disableGestures={this.state.disableGestures}
                    toleranceX={0}
                    edgeHitWidth={window.width/5}
                    openMenuOffset={window.width/5}>
                <View style={styles.container}>
                    {this.renderListView()}
                </View>
                <MenuButton 
                    selected={this.state.enoughSelections}
                    source={require('../img/menu-btn.png')}
                    resize={'contain'}
                    onPress={this.onMenuPress} />
            </SideMenu>
    },
    //menu press function 
    onMenuPress: function() {
        this.eventEmitter.emit('toggleMenu');
    }, 
    //loading render
    renderLoadingView: function() {
        return (
            <View style={styles.container}>
                <Spinner style={styles.spinner} isVisible={!this.state.isLoaded} size={50} type={'Arc'} color={'#FF0000'}/>
            </View>
        );
    }, 
    //rendering list view
    renderListView: function() {
        return (
                <ListView
                    dataSource = {this.state.dataSource}
                    initialListSize = {5}
                    pageSize={5}
                    renderRow  = {this.renderEntry} />
        );
    }, 
    //rendering rows within list view
    renderEntry: function(entry) {

        if (typeof entry.mediaGroups === 'undefined')
        {
            return (
                <ArticlePreview
                    category={entry.categories[0]}
                    key={entry.title}
                    heartText={'2.9k'}
                    categoryPress={this.onCategoryDetailsPress}
                    selected={false}
                    source={require('../img/stock_image.png')}
                    text={entry.title.toLowerCase().replace('&nbsp;','')}
                    onPress={() => this.onArticleDetailsPress(entry)} />
            );
        } else 
        { 
            var url = entry.mediaGroups[0].contents[0].url; 
            if (url.indexOf('w=150') > -1)
            {
                url.replace("w=150", "w=500");
            }
            var catsource = entry.categories[0]; 
            if (typeof catsource == "undefined")
            {
                catsource = "News";
            }
            return (
                <ArticlePreview
                    category={catsource}
                    key={entry.title}
                    heartText={'2.9k'}
                    categoryPress={this.onCategoryDetailsPress}
                    selected={false}
                    source={{uri: url }}
                    text={entry.title.toLowerCase().replace('&nbsp;','')}
                    onPress={() => this.onArticleDetailsPress(entry)} />
            );
        }

    },
    //pressing category button to go to feed of that category 
    onCategoryDetailsPress: function() {
        //forward to sytled web view of categorical article feed
        console.log("onCategoryDetailsPress"); 
    }, 
    //press to see article's details 
    onArticleDetailsPress: function(entry) {
        //forward to sytled web view of article details given link
        console.log("onArticleDetailsPress"); 
        console.log(entry);

        //asynchronously store entry

        //pushing to new component
        this.props.navigator.push({
            name: 'articledetails',
            passProps: {entry: entry},
        });
    }, 
    /*
    onChange: function(event, articles) {
        this.setState({articles: articles}); //trigers re-render of component
    }
    */

});

The problem is that i can navigate to the other pages because the Menu component referenced in the SideMenu does not have Navigator as a part of it - so pushing to the next page is meaningless to it. Is there a better way to implement this? I can give you access to the repo if needed.

Kureev commented 8 years ago

But you're adding <Menu events={this.eventEmitter} navigate={this.navigate} /> as a menu, so you should have a navigate method inside.

I think the reason may be in the design of component. If you can explain what happens here I can probably advice you how to solve it.

Btw, I think it's better to ask this kind of questions on stackoverflow and cc me, I'd like to keep issues only for bugs.

robtg4 commented 8 years ago

I'll bring this to stackoverflow and cc u

robtg4 commented 8 years ago

http://stackoverflow.com/questions/34417144/create-a-side-menu-home-page-with-react-native-navbar-react-native-router-flux