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({})
There is a circular dependency between
App.jsandHomeScreen.jsfiles. InApp.js, you are importing theHomeScreencomponent, and inHomeScreen.js, you are importing theAppcomponent. This circular dependency can lead to unexpected behavior. To fix this, you should create a separate file for the drawer navigator and move theMyDrawercomponent fromHomeScreen.jsto the new file. Then, import the drawer navigator component inApp.jsand use it as the initial screen.And Double-check that the screen names in your navigation stack match the ones used in the navigator.