Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-native - undefined is not a function (evaluating navigation.openDrawer()')

I'm very new to React native. I'm going to share my codes here App.js

import React, {Component} from 'react';
import Routes from './src/Routes';

export default class App extends Component {

  render() {
    return (
      <Routes />
    );
  }
}

index.js

import React, { Component } from 'react';
import { AppRegistry, Dimensions } from 'react-native';
import { createDrawerNavigator } from 'react-navigation';
import App from './App';
import {name as appName} from './app.json';
import SideMenu from './src/SideMenu'
import Routes from './src/Routes';

const drawernav = createDrawerNavigator({
  Item1: {
      screen: Routes,
    }
  }, {
    contentComponent: SideMenu,
    drawerWidth: Dimensions.get('window').width - 120,  
});

AppRegistry.registerComponent(appName, () => drawernav);
AppRegistry.registerComponent(appName, () => App);

Routes.js

import React, {Component} from 'react';
import { createStackNavigator, createAppContainer, createDrawerNavigator, DrawerActions } from 'react-navigation';
import Home from './Home';
import Settings from './Settings';
import SideMenu from './SideMenu';
import { Button, Platform, StyleSheet, Text, View, TouchableOpacity } from 'react-native';

const Nav = createStackNavigator({
  Home: {
    screen: Home,
    navigationOptions: ({navigation}) => ({
      title: "Home",
      headerLeft:(<TouchableOpacity onPress={() => navigation.openDrawer()}>
                <Text >Button</Text>
              </TouchableOpacity>
   ),
  })
 },
  Settings: {
screen: Settings,
navigationOptions: ({navigation}) => ({
  title: "Settings",
})     
  },
});
const Routes = createAppContainer(Nav);
export default Routes;

SideNav.js

import PropTypes from 'prop-types';
import React, {Component} from 'react';
import styles from './SideMenu.style';
import {NavigationActions} from 'react-navigation';
import {ScrollView, Text, View} from 'react-native';
import Home from './Home';
import Settings from './Settings';

class SideMenu extends Component {
  navigateToScreen = (route) => () => {
    const navigateAction = NavigationActions.navigate({
      routeName: route
    });
    this.props.navigation.dispatch(navigateAction);
  }

  render () {
    return (
      <View style={styles.container}>
        <ScrollView>
          <View>
            <Text style={styles.sectionHeadingStyle}>
              Section 1
            </Text>
            <View style={styles.navSectionStyle}>
              <Text style={styles.navItemStyle} onPress= 
   {this.navigateToScreen('Settings')}>
                  Page1
              </Text>
            </View>
          </View>
          <View>
            <Text style={styles.sectionHeadingStyle}>
              Section 2
            </Text>
            <View style={styles.navSectionStyle}>
              <Text style={styles.navItemStyle} onPress= 
   {this.navigateToScreen('Home')}>
                    Page2
              </Text>
              <Text style={styles.navItemStyle} onPress= 
   {this.navigateToScreen('Settings')}>
                    Page3
              </Text>
            </View>            
          </View>
          <View>
            <Text style={styles.sectionHeadingStyle}>
              Section 3
            </Text>
            <View style={styles.navSectionStyle}>
              <Text style={styles.navItemStyle} onPress= 
   {this.navigateToScreen('Settings')}>
                  Page4
              </Text>
            </View>
          </View>
        </ScrollView>
        <View style={styles.footerContainer}>
          <Text>This is my fixed footer</Text>
        </View>
      </View>
    );
  }
}

SideMenu.propTypes = {
  navigation: PropTypes.object
};

export default SideMenu;

Home.js

import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';

export class Home extends Component {
  render() {
    return (
      <View >
        <Text>This is the home screen</Text>
        <Button onPress={() => this.props.navigation.navigate('Settings')} title="Settings"/>
      </View>
    )
  }
}

export default Home

When I click the button in the header, I get the error

undefined is not a function (evaluating navigation.openDrawer()')

I really dont mean to do this but I'm really desperate right now. I've spent two days trying to figure how to make a side menu and I'm really disappointed in this framework. You wont even spend 5 mins to create a side menu in Ionic. Kindly help on this. Project available on git https://github.com/yinka1255/react.git

like image 305
Yinka Avatar asked Jan 16 '19 17:01

Yinka


1 Answers

The error

undefined is not a function (evaluating navigation.openDrawer()')

is being thrown because the navigation prop does not have an openDrawer method. Instead, you need to use the dispatch method and the DrawerActions helper:

import { DrawerActions } from 'react-navigation'
...
const Nav = createStackNavigator({
  Home: {
    screen: Home,
    navigationOptions: ({navigation}) => ({
      title: "Home",
      headerLeft:(
        <TouchableOpacity onPress={() => navigation.dispatch(DrawerActions.openDrawer())}>
          <Text>Button</Text>
        </TouchableOpacity>
      ),
    })
  },

DrawerActions has three methods that each return dispatchable actions. openDrawer, closeDrawer, and toggleDrawer which will toggle the Drawer state from open to closed and vice versa. Hope that helps!

like image 122
Robbie Milejczak Avatar answered Oct 22 '22 01:10

Robbie Milejczak