I'm trying to create choose language screen on first app launch in React Native.
So far I have managed to get the first screen working, but once I click on button to select language error throws with the following debugging message:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
I have used all the hooks inside component function body, but I assume it's because I have used useEffet
hook and async
function at once, therefore conflict has been created.
App.js
import React, {useEffect, useState} from "react";
import Login from "./login.js";
import Register from "./register.js";
import Dashboard from "./dashboard.js";
import { NavigationContainer, useNavigation } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import { Text, View, Button } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
const Stack = createStackNavigator();
const HAS_LAUNCHED = "hasLaunched";
const ENGLISH = "en";
const HEBREW = "he";
function setAppLaunched(en) {
const navigation = useNavigation();
AsyncStorage.setItem(HAS_LAUNCHED, "true");
AsyncStorage.setItem(en ? ENGLISH : HEBREW, "true");
navigation.navigate("Login");
}
function CheckIfFirstLaunch() {
const selectLaunched = (value) => {
setAppLaunched(value);
};
return (
<View>
<Text>Choose Language</Text>
<Button onPress={() => selectLaunched(false)} title="Hebrew"/>
<Button onPress={() => selectLaunched(true)} title="English"/>
</View>
);
}
export default function App() {
const [selected, setSelected] = useState(false);
const verifyHasLaunched = async () => {
try {
const hasLaunched = await AsyncStorage.getItem(HAS_LAUNCHED);
setSelected(hasLaunched != null);
} catch (err) {
setSelected(false);
}
};
useEffect(() => verifyHasLaunched);
if (!selected){
return <CheckIfFirstLaunch onSelect={() => setSelected(true)} />;
}
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{headerShown: false}} initialRouteName="Login">
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Register" component={Register} />
<Stack.Screen name="Dashboard" component={Dashboard} />
</Stack.Navigator>
</NavigationContainer>
);
}
How can I avoid the conflict with useEffect
hook and async
function?
Read more here: https://stackoverflow.com/questions/65718299/using-react-hooks-inside-function-returns-invalid-hook-call
Content Attribution
This content was originally published by Yotam at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.