You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Expo Go安卓端hooks与NavigationContainer报错求助

问题说明

我这段代码里没在useEffect里调用Hook,也加了NavigationContainer,其他文件也没毛病。用Expo Web Build在网页上跑正常,但用Expo Go在安卓手机上跑就报4个错:

  • 提示“请勿在useEffect()、useMemo()或其他内置Hooks中调用hooks”;
  • 提示“找不到navigation对象,你的组件是否在NavigationContainer内部?”(这个错出现3次)

代码如下:

import React, { useEffect, useState } from "react";
import { View, Image } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { NavigationContainer } from '@react-navigation/native';

import VehicleList from "./owner/vehicle-list";
import Login from "./authenticate/login";
import RegisterUser from "./authenticate/register";
import '../global.css'

const Stack = createNativeStackNavigator();

export default function App() {

    const [loading, setLoading] = useState(true);
    const [initialRouteName, setInitialRouteName] = useState("Login");

    useEffect(() => {
        const checkToken = async () => {
            try {
                const userToken = await AsyncStorage.getItem("token");
                if (userToken) {
                    const parsedToken = JSON.parse(userToken);
                    if (parsedToken && parsedToken.isValid) {
                        setInitialRouteName("VehicleList");
                    }
                }
            } catch (error) {
                console.error("Error checking token:", error);
            }
            setLoading(false);
        };

        checkToken();
    }, []);

    if (loading) return (
        <View className="flex-1" >
            <Image className="w-full h-full" resizeMode="cover" source={require('../assets/images/splash.png')} />
        </View>    
        );

    return (
        <NavigationContainer>
            <Stack.Navigator initialRouteName={initialRouteName}>
                <Stack.Screen name="Home" options={{title: 'Home'}} component={VehicleList} />
                <Stack.Screen name="Login" options={{title: false}} component={Login} />
                <Stack.Screen name="Register" component={RegisterUser} />
            </Stack.Navigator>
        </NavigationContainer>
    );
}

补充:网页构建的时候必须删掉NavigationContainer,不然会提示“不能在NavigationContainer中嵌套NavigationContainer”,但加上这个容器后安卓的问题还是没解决。


解决办法

1. 修正路由名称不匹配的问题

你代码里登录成功后把初始路由设成了VehicleList,但导航栈里对应的屏幕名称是Home,这明显不匹配!这会导致导航找不到正确的初始页面,间接引发导航相关错误。

修改useEffect里的代码:

if (parsedToken && parsedToken.isValid) {
    setInitialRouteName("Home"); // 改成导航栈里定义的屏幕名
}

2. 检查子组件的Hook调用是否违规

虽然你的App组件里没在useEffect里调用Hook,但子组件(VehicleList、Login、RegisterUser)可能存在问题:

  • 在useEffect、useMemo内部调用了useNavigation()、useRoute()这类Hook;
  • 在条件判断、循环或者嵌套函数里调用Hook。

所有子组件都要排查一遍,确保Hook都在组件最顶层作用域调用,别放在任何内置Hook、if语句或者嵌套函数里。

3. 解决“找不到navigation对象”的问题

这个错误出现3次,大概率是子组件用了useNavigation()但没被NavigationContainer正确包裹。可能的原因:

  • 启动页(loading状态返回的页面)里如果嵌套了需要调用导航Hook的组件,此时还没渲染NavigationContainer,必然报错。检查启动页是否有这类组件,或者确保只有NavigationContainer渲染后,使用导航Hook的组件才会加载;
  • 子组件违规使用导航Hook,比如在组件外部直接调用useNavigation(),或者在非组件函数里使用。

4. 处理网页端的嵌套冲突

网页端提示不能嵌套NavigationContainer,可能是Expo Web的配置或第三方库已经自动添加了一个容器。可以通过平台判断来控制渲染:

先导入Platform:

import { Platform } from 'react-native';

再修改返回部分的代码:

return (
    <>
        {Platform.OS !== 'web' && <NavigationContainer>}
            <Stack.Navigator initialRouteName={initialRouteName}>
                <Stack.Screen name="Home" options={{title: 'Home'}} component={VehicleList} />
                <Stack.Screen name="Login" options={{title: false}} component={Login} />
                <Stack.Screen name="Register" component={RegisterUser} />
            </Stack.Navigator>
        {Platform.OS !== 'web' && </NavigationContainer>}
    </>
);

这样网页端不会渲染自定义的NavigationContainer,避免嵌套冲突,安卓端则正常保留容器。


内容的提问来源于stack exchange,提问作者ShivamQmr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 12:04:53