Navigation in my drawer won't work ( ERROR TypeError: Cannot read property 'emit' of undefined, js engine: hermes)

397 Views Asked by At

I'm working on navigation drawer that allows me to navigate between pages when clicking on each one. However, whenever I try to click on any of the pages in the drawer, the error, " ERROR TypeError: Cannot read property 'emit' of undefined, js engine: hermes" comes up. I am very new to react native and I'm not sure how to fix this. I am currently testing this on an android device if that helps.

Here's my code:

App.js

import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import LogInScreen from './Screens/LogInScreen';
import HomeScreen from './Screens/HomeScreen';
import RecordHours from './Screens/DrawerComponents/RecordHours';


const Stack = createNativeStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen options={{headerShown: false}}name="LogIn" component={LogInScreen} />
        <Stack.Screen options={{headerShown: false}}name="HomeScreen" component={HomeScreen} />
        <Stack.Screen options={{headerShown: false}}name="Record Hours" component={RecordHours} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

HomeScreen.js

import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, SafeAreaView, Alert } from 'react-native'; // Add Alert import
import { createDrawerNavigator } from '@react-navigation/drawer';
import { DrawerContentScrollView, DrawerItemList, DrawerItem } from '@react-navigation/drawer';
import { getAuth, signOut } from 'firebase/auth';
import RecordHours from './DrawerComponents/RecordHours';
import 'react-native-gesture-handler';


const Drawer = createDrawerNavigator();
const auth = getAuth();

const CustomDrawerContent = ({ navigation, ...props }) => {
  const handleSignOut = () => {
    signOut(auth)
      .then(() => {
        navigation.replace('LogIn');
      })
      .catch((error) => Alert.alert('Error', error.message));
  };  

  return (
    <DrawerContentScrollView {...props}>
      <DrawerItemList {...props} />
      <DrawerItem label="Sign Out" onPress={handleSignOut} />
    </DrawerContentScrollView>
  );
};



const MyDrawer = () => {
  return (
    <Drawer.Navigator drawerContent={(props) => <CustomDrawerContent navigation={props.navigation} {...props} />}>
      <Drawer.Screen name="Home" component={App} />
      <Drawer.Screen name="Record Hours" component={RecordHours} />
    </Drawer.Navigator>
  );
};


const App = () => {
  const [hours, setHours] = useState(0);

  const increaseHours = () => {
    setHours(hours + 1);
  };

  const decreaseHours = () => {
    if (hours > 0) {
      setHours(hours - 1);
    }
  };

  const currentUserEmail = auth.currentUser ? auth.currentUser.email : '';

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.content}>
        <Text>Email: {currentUserEmail}</Text>
        <Text style={styles.hoursText}>Total Hours: {hours}</Text>
        <TouchableOpacity style={styles.button} onPress={increaseHours}>
          <Text style={styles.buttonText}>Add Hour</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.button} onPress={decreaseHours}>
          <Text style={styles.buttonText}>Remove Hour</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  content: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  hoursText: {
    fontSize: 20,
    marginBottom: 20,
  },
  button: {
    backgroundColor: '#2196f3',
    padding: 10,
    borderRadius: 5,
    marginBottom: 10,
  },
  buttonText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: 'bold',
  },
});

export default function Apps() {
  return (
    <MyDrawer />
  );
}

LogInScreen.js

import { ImageBackground, KeyboardAvoidingView, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'
// import React from 'react'
import React, { useEffect, useState } from "react";
import { auth } from '../firebase';
import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword } from "firebase/auth";
import { useNavigation } from '@react-navigation/native';



const LogInScreen = () => {
    const [email, setEmail] = useState('')
    const [password, setPassword] = useState('')


    const navigation = useNavigation()

    useEffect(() => {
        const unsubscribe = auth.onAuthStateChanged(user => {
            if(user){
                navigation.navigate("HomeScreen")
            }
        })

        return unsubscribe
    }, [])

    const handleSignUp = () => {
        const auth = getAuth();
        createUserWithEmailAndPassword(auth, email, password)
        .then((userCredential) => {
        // Signed in 
        const user = userCredential.user;
        console.log('Registered with  ', user.email)
                                    })
        .catch((error) => {
        const errorCode = error.code;
        const errorMessage = error.message;
    // ..
                        });
    }

    const handleLogin = () => {
        const auth = getAuth();
        signInWithEmailAndPassword(auth, email, password)
        .then((userCredential) => {
            // Signed in 
            const user = userCredential.user;
            console.log('Logged in with ', user.email)
                                        })
        .catch((error) => {
        const errorCode = error.code;
        const errorMessage = error.message;
        alert("Sign-in unsuccessfull: " + errorMessage)
        });
    }
      
  return (
    
    <>
      <KeyboardAvoidingView
          style={styles.container}
      >
              <View style={styles.inputContainer}>
                  <TextInput
                      placeholder="Email"
                      value={email}
                      onChangeText={text => setEmail(text)}
                      style={styles.input} />

                  <TextInput
                      placeholder="Password"
                      value={password}
                      onChangeText={text => setPassword(text)}
                      style={styles.input}
                      secureTextEntry />
              </View>

              <View style={styles.buttonContainer}>
                  <TouchableOpacity
                      onPress={handleLogin}
                      style={styles.button}
                  >
                      <Text style={styles.buttonText}>Login</Text>
                  </TouchableOpacity>
                  <TouchableOpacity
                      onPress={handleSignUp}
                      style={[styles.button, styles.buttonOutline]}
                  >
                      <Text style={styles.buttonOutlineText}>Register</Text>
                  </TouchableOpacity>
              </View>

          </KeyboardAvoidingView></>
  )
}

export default LogInScreen

const styles = StyleSheet.create({
    container: {

        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    inputContainer:{
        width:'80%'
    },
    input:{
        backgroundColor:'white',
        paddingHorizontal:15,
        paddingVertical: 10,
        borderRadius: 10,
        marginTop: 5,
    },
    buttonContainer:{
        width:'60%',
        justifyContent: 'center',
        alignItems: 'center',
        marginTop: 40,
    },
    button:{
        backgroundColor: '#24A0ED',
        width: '100%',
        padding: 15,
        borderRadius: 10,
        alignItems: 'center',
    },
    buttonOutline:{
        backgroundColor: 'white',
        marginTop: 5,
        borderColor: '#24A0ED',
        borderWidth: 2,
    },
    buttonText:{
        color: 'white',
        fontWeight: '700',
        fontSize: 16,
    },
    buttonOutlineText:{
        color: '#24A0ED',
        fontWeight: '700',
        fontSize: 16,
    },
})

RecordHours.js

import { StyleSheet, Text, View } from 'react-native'
import React from 'react'

const RecordHours = () => {
  return (
    <View>
      <Text>RecordHours</Text>
    </View>
  )
}

export default RecordHours

const styles = StyleSheet.create({})
1

There are 1 best solutions below

0
Anay On

There is a circular dependency between App.js and HomeScreen.js files. In App.js, you are importing the HomeScreen component, and in HomeScreen.js, you are importing the App component. This circular dependency can lead to unexpected behavior. To fix this, you should create a separate file for the drawer navigator and move the MyDrawer component from HomeScreen.js to the new file. Then, import the drawer navigator component in App.js and use it as the initial screen.

And Double-check that the screen names in your navigation stack match the ones used in the navigator.