当我从初始屏幕导航到语言选择屏幕时,我收到此错误,我尝试了所有方法,但我不知道为什么,我尝试使用“useNavigation”,但它仍然给出错误,所以我坚持使用此方法,而不是应用程序基本上应该基本上路由使用应用程序导航器从初始屏幕到语言选择屏幕:
ERROR TypeError: Cannot read property 'navigate' of undefined, js engine: hermes
这是我的代码
initial screen
:
import { observer } from "mobx-react-lite";
import React, { FC } from "react";
import { Image, ImageStyle, TextStyle, View, ViewStyle, TouchableOpacity } from "react-native";
import { Text } from "../components";
import { AppStackScreenProps } from "../navigators/AppNavigator";
import { colors, spacing, typography } from "../theme";
import { useNavigation } from "expo-router";
const whiteCloudImage = require("../../assets/images/white-cloud.png");
const skylineImage = require("../../assets/images/skyline.png");
interface InitialScreenProps extends AppStackScreenProps<"Initial"> { }
export const InitialScreen: FC<InitialScreenProps> = observer(function InitialScreen({ navigation }) {
const navigateToAuth = () => {
navigation.navigate("LanguageSelection");
};
return (
<TouchableOpacity style={$safeArea} onPress={navigateToAuth}>
<View style={$topContainer}>
<Image source={whiteCloudImage} style={$firstCloudImage} resizeMode="contain" />
<Image source={whiteCloudImage} style={$secondCloudImage} resizeMode="contain" />
</View>
<View style={$container}>
<View style={$centerContainer}>
<Text style={$brandName}>likwid</Text>
<Text style={$slogan}>Building relationships</Text>
</View>
</View>
<View style={$bottomContainer}>
<Image source={skylineImage} style={$bottomImage} resizeMode="cover" />
<Text style={$version}>Version 1.0</Text>
</View>
</TouchableOpacity>
);
});
const $safeArea: ViewStyle = {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: colors.background,
};
const $topContainer: ViewStyle = {
position: "absolute",
top: 0,
left: 0,
right: 0,
zIndex: 10,
};
const $firstCloudImage: ImageStyle = {
position: "absolute",
top: 30,
left: 16,
width: "55%",
height: undefined,
aspectRatio: 1,
};
const $secondCloudImage: ImageStyle = {
position: "absolute",
top: 80,
left: 250,
width: "50%",
height: undefined,
aspectRatio: 1,
};
const $container: ViewStyle = {
flex: 1,
justifyContent: "center",
alignItems: "center",
width: "100%",
};
const $centerContainer: ViewStyle = {
flex: 1,
justifyContent: "center",
alignItems: "center",
padding: spacing.md,
};
const $bottomContainer: ViewStyle = {
position: "absolute",
bottom: 0,
width: "100%",
alignItems: "center",
};
const $bottomImage: ImageStyle = {
width: "100%",
height: 200,
};
const $brandName: TextStyle = {
color: "#FFD43B",
fontSize: 48,
fontWeight: "bold",
lineHeight: 58,
fontFamily: typography.bold.normal,
};
const $slogan: TextStyle = {
color: "#4A483B",
fontSize: 24,
fontFamily: typography.openSans.bold,
};
const $version: TextStyle = {
color: "#4A483B",
fontSize: 16,
zIndex: 1,
position: "absolute",
bottom: 10,
};
代码
LanguageSelection screen
:
import { observer } from "mobx-react-lite";
import React, { FC } from "react";
import {
ImageStyle,
TextStyle,
View,
SafeAreaView,
ViewStyle,
TouchableOpacity,
} from "react-native";
import { Text } from "../../components";
import { AppStackScreenProps } from "../../navigators";
import { colors, typography } from "../../theme";
import LanguageSelector from "../../components/LanguageSelectorButtont";
import { ArrowLeftIcon } from "../../components/icons";
interface LanguageSelectionScreenProps extends AppStackScreenProps<"LanguageSelection"> { }
export const LanguageSelectionScreen: FC<LanguageSelectionScreenProps> = observer(
function LanguageSelectionScreen({ navigation }) {
const navigateToCreateAccount = () => {
navigation.navigate("Welcome");
};
const navigateBack = () => {
navigation.navigate("Initial");
};
const handleLanguageChange = () => { };
return (
<SafeAreaView style={$safeArea}>
<TouchableOpacity onPress={navigateBack} style={$backButton}>
<ArrowLeftIcon />
</TouchableOpacity>
<View style={$container}>
<View style={$contentWrapper}>
<View style={$centerContainer}>
<Text style={$welcomeText}>Welcome to</Text>
{/* <Text style={$welcomeText} tx="selectAuthScreen.welcomeText" /> */}
<Text text=" " />
<Text style={$brandName}>likwid</Text>
{/* <Text style={$brandName} tx="initialScreen.brandName" /> */}
</View>
</View>
<View style={$textContainer}>
<View
style={{
marginBottom: 20,
}}
>
<Text style={$subText}>Please select your language</Text>
{/* <Text style={$subText} tx="languageSelectionScreen.selectText" /> */}
</View>
<LanguageSelector onPress={handleLanguageChange} />
</View>
</View>
<View style={$bottomContainer}>
<TouchableOpacity style={$buttonBlueBackground} onPress={navigateToCreateAccount}>
<Text style={$buttonTextWhite}>Continue</Text>
{/* <Text style={$buttonTextWhite} tx="languageSelectionScreen.continue" /> */}
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
);
const $safeArea: ViewStyle = {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: colors.background,
};
const $backButton: ViewStyle = {
alignSelf: "flex-start",
marginLeft: 20,
marginBottom: 50,
};
const $container: ViewStyle = {
flex: 1,
justifyContent: "flex-start",
alignItems: "center",
width: "100%",
marginTop: 80,
};
const $contentWrapper: ViewStyle = {
alignItems: "center",
};
const $centerContainer: ViewStyle = {
flexDirection: "row",
alignItems: "baseline",
};
const $firstCloudImage: ImageStyle = {
width: "50%",
height: undefined,
aspectRatio: 1,
marginTop: 40,
};
const $welcomeText: TextStyle = {
color: "#4A483B",
textAlign: "center",
fontFamily: typography.openSans.regular,
fontSize: 32,
fontStyle: "normal",
fontWeight: "700",
lineHeight: 68,
};
const $textContainer: ViewStyle = {
alignItems: "center",
marginTop: 120,
};
const $subText: TextStyle = {
color: "#B3B3B3",
textAlign: "center",
fontFamily: typography.dmSans.regular,
fontSize: 16,
fontStyle: "normal",
fontWeight: "500",
lineHeight: 22,
letterSpacing: 0.02,
};
const $brandName: TextStyle = {
color: "#FFD43B",
fontFamily: typography.bold.normal,
fontSize: 32,
fontStyle: "normal",
fontWeight: "400",
lineHeight: 58,
};
const $bottomContainer: ViewStyle = {
paddingBottom: 20,
};
const $buttonWhiteBackground: ViewStyle = {
backgroundColor: "#FFFFFF",
paddingVertical: 7.5,
paddingHorizontal: 15,
borderRadius: 25,
alignItems: "center",
marginBottom: 10,
width: 240,
alignSelf: "center",
shadowColor: "#000",
shadowOffset: { width: 1, height: 1 },
shadowOpacity: 0.25,
shadowRadius: 2,
elevation: 5,
};
const $buttonBlueBackground: ViewStyle = {
backgroundColor: "#007bff",
paddingVertical: 7.5,
paddingHorizontal: 15,
borderRadius: 25,
alignItems: "center",
width: 240,
alignSelf: "center",
};
const $buttonTextBlue: TextStyle = {
color: "#007bff",
fontSize: 16,
fontWeight: "bold",
};
const $buttonTextWhite: TextStyle = {
color: "#FFFFFF",
fontSize: 16,
fontWeight: "bold",
};
AppNavigator.tsx:
import {
DarkTheme,
DefaultTheme,
NavigationContainer,
NavigatorScreenParams,
RouteProp,
} from "@react-navigation/native";
import { createNativeStackNavigator, NativeStackScreenProps } from "@react-navigation/native-stack";
import { observer } from "mobx-react-lite";
import React from "react";
import { useColorScheme } from "react-native";
import * as Screens from "../screens";
import Config from "../config";
import { useStores } from "../models";
import { HomeNavigator, HomeTabParamList } from "./HomeNavigator";
import { navigationRef, useBackButtonHandler } from "./navigationUtilities";
import { colors } from "../theme";
import { ManagerNavigator } from "./ManagerNavigator";
import { BasicNavigator } from "./BasicNavigator";
import { CustomerNavigator } from "./CustomerNavigator";
import { NativeStackNavigationProp } from "react-native-screens/lib/typescript/native-stack/types";
export type AppStackParamList = {
Welcome: undefined;
Initial: undefined;
SelectAuth: undefined;
CreateAccount: undefined;
Login: undefined;
CustomerLogin: undefined;
Register: undefined;
CustomerRegister: undefined;
MerchantRegister: undefined;
Home: NavigatorScreenParams<HomeTabParamList>;
Launch: undefined;
LanguageSelection: undefined;
MemberLogin: undefined;
SelectAccountLogin: undefined;
AccountSetup: undefined;
};
const exitRoutes = Config.exitRoutes;
export type AppStackScreenProps<T extends keyof AppStackParamList> = {
navigation: NativeStackNavigationProp<AppStackParamList, T>;
route: RouteProp<AppStackParamList, T>;
};
const Stack = createNativeStackNavigator<AppStackParamList>();
const AppStack = observer(function AppStack() {
const {
authenticationStore: { isAuthenticated, authRole },
} = useStores();
const RenderNavigator = () => {
switch (authRole) {
case "Retailer":
return <HomeNavigator />;
case "Manager":
return <ManagerNavigator />;
case "Basic":
return <BasicNavigator />;
case "User":
return <CustomerNavigator />;
default:
return <HomeNavigator />;
}
};
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{ headerShown: false, navigationBarColor: colors.background }}
initialRouteName={isAuthenticated ? "Home" : "Initial"}
>
{isAuthenticated ? (
<>
<Stack.Screen name="Home" component={RenderNavigator} />
</>
) : (
<>
<Stack.Screen name="Login" component={Screens.LoginScreen} />
<Stack.Screen name="CustomerLogin" component={Screens.CustomerLoginScreen} />
<Stack.Screen name="Register" component={Screens.RegisterScreen} />
<Stack.Screen name="CustomerRegister" component={Screens.CustomerRegisterScreen} />
<Stack.Screen name="MerchantRegister" component={Screens.MerchantRegisterScreen} />
<Stack.Screen name="MemberLogin" component={Screens.MemberLoginScreen} />
<Stack.Screen name="Initial" component={Screens.InitialScreen} />
<Stack.Screen name="Welcome" component={Screens.WelcomeScreen} />
<Stack.Screen name="LanguageSelection" component={Screens.LanguageSelectionScreen} />
<Stack.Screen name="SelectAuth" component={Screens.SelectAuthScreen} />
<Stack.Screen name="Launch" component={Screens.LaunchScreen} />
<Stack.Screen name="CreateAccount" component={Screens.CreateAccountScreen} />
<Stack.Screen name="SelectAccountLogin" component={Screens.SelectAccountLoginScreen} />
</>
)}
</Stack.Navigator>
</NavigationContainer>
);
});
export interface NavigationProps
extends Partial<React.ComponentProps<typeof NavigationContainer>> { }
export const AppNavigator = observer(function AppNavigator(props: NavigationProps) {
const colorScheme = useColorScheme();
useBackButtonHandler((routeName) => exitRoutes.includes(routeName));
return (
<NavigationContainer
ref={navigationRef}
theme={colorScheme === "dark" ? DarkTheme : DefaultTheme}
{...props}
>
<AppStack />
</NavigationContainer>
);
});
尝试手动定义导航常量,而不是将其作为 prop 传递。
const navigation = useNavigation();
然后
navigation.navigate("LanguageSelection");