L.Calvin
L.Calvin

Reputation: 251

Issue with UseNavigation in react native expo in App.js (Followed up from the previous issue)

Another issue that arrives from the previous issue: Issues with header button in React Native Expo

After changing from ../firebase to ./firebase. It says it couldnt find variable of navigation. So I import { useNavigation } from '@react-navigation/core' and also added const navigation = useNavigation(). But I am having the issue of

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

It seems to be able to sign out as I have the console logging of Signed Out Successfully but it cannot navigate back to the login

Am I doing something wrong here? My idea of adding this button on the right side at the border is for the user to be able to sign out faster when the user is logged in the app

Updated App.js

import { StatusBar } from 'expo-status-bar';
import React from 'react'
import { signOut } from 'firebase/auth';
import { auth } from './firebase';
import { useNavigation } from '@react-navigation/core'
import { StyleSheet, Text, View, Button } 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 RegisterScreen from './screens/RegisterScreen';
import ForgetPasswordScreen from './screens/ForgetPasswordScreen';
import SubScreen1 from './screens/SubScreen1';
import SubScreen2 from './screens/SubScreen2';

const Stack = createNativeStackNavigator();
const navigation = useNavigation()

const handleSignOut = async () =>{
  
  try{
    await signOut(auth)
    console.log("Signed out successfully")
    navigation.replace("Login")
  }catch (error) {
    console.log({error});
}
}
export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen options= {{ headerShown : false }} name="Login" component={LoginScreen} />
        <Stack.Screen name="Home" component={HomeScreen} options={{headerRight: () => (
            <Button
              onPress={handleSignOut}
              title="Sign Out"
              color="#0782F9" /> ),}} />
        <Stack.Screen name="Register" component={RegisterScreen} />
        <Stack.Screen name="Forget Password" component={ForgetPasswordScreen} />
        <Stack.Screen name="SubScreen1" component={SubScreen1} options={{ title: 'Search Result' }}/>
        <Stack.Screen name="SubScreen2" component={SubScreen2} options={{ title: 'Random Search Result' }}/>
      </Stack.Navigator>
    </NavigationContainer>
  );
}

Upvotes: 1

Views: 642

Answers (1)

Dev-Siri
Dev-Siri

Reputation: 731

You are breaking the rules of hooks in React. Its basically initializing the hook outside a component.

Put the hooks inside the component like here:

export default function App() {
  // Use the hook here
  const navigation = useNavigation();

  // Add the function here also, its generally preferred to
  // put functions inside the componenent so it can get access to hooks. Or you can also
  // pass the hook as an argument if you prefer.
  const handleSignOut = async () => {
    try {
      await signOut(auth);
      console.log("Signed out successfully");
      navigation.replace("Login");
    } catch (error) {
      console.log({ error });
    }
  }

  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen options= {{ headerShown : false }} name="Login" component={LoginScreen} />
        <Stack.Screen name="Home" component={HomeScreen} options={{headerRight: () => (
            <Button
              onPress={handleSignOut}
              title="Sign Out"
              color="#0782F9" /> ),}} />
        <Stack.Screen name="Register" component={RegisterScreen} />
        <Stack.Screen name="Forget Password" component={ForgetPasswordScreen} />
        <Stack.Screen name="SubScreen1" component={SubScreen1} options={{ title: 'Search Result' }}/>
        <Stack.Screen name="SubScreen2" component={SubScreen2} options={{ title: 'Random Search Result' }}/>
      </Stack.Navigator>
    </NavigationContainer>
  );
}

Hope this helps.

Upvotes: 1

Related Questions