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

React Native导航未挂载时调用导航仍报错求助

React Native导航初始化错误排查与解决

遇到的错误

ERROR  'navigation' 对象尚未初始化。
出现此问题可能是因为没有挂载导航器,或者导航器尚未完成挂载。

最初的代码

const Stack = createNativeStackNavigator();

export default function App() {
    const navigation = useNavigation();
    ...

    useEffect(() => {
      const subscriber = auth.onAuthStateChanged((_user) => {
        if (!_user) {
          navigation.navigate('Login'); 
          ...
        }
        else {
          navigation.navigate('CoreTabs', { screen: 'Home' })
        }
      });
      return subscriber;
    },[]);

调整后的代码(仍报错)

const Stack = createNativeStackNavigator();

export default function App() {
    // const navigation = useNavigation(); // 已移除
    const navigationRef = useNavigationContainerRef();  // 已添加
    ...
    useEffect(() => {
      const subscriber = auth.onAuthStateChanged((_user) => {
        if (!_user) {
          // navigation.navigate('Login'); // 已移除
          if (navigationRef.isReady) navigationRef.navigate('Login');  // 已添加
        }
        else {
          ...
          // navigation.navigate('CoreTabs', { screen: 'Home' }) // 已移除
          if (navigationRef.isReady) navigationRef.navigate('CoreTabs', { screen: 'Home' }) // 已添加
        }
      });
      return subscriber;
    },[]);

当前的NavigationContainer配置

return (
      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Group>
            { user && <Stack.Screen name="CoreTabs" component={CoreTabs} /> }
            <Stack.Screen name="Login" component={LoginScreen} />
            <Stack.Screen name="Registration" component={RegistrationScreen}/>
            <Stack.Screen name="Reset Password" component={ResetPasswordScreen}/>
          </Stack.Group>
          <Stack.Group screenOptions={{ presentation: 'modal' }}>
            <Stack.Screen name="Notifications" component={NotificationsScreen} />
            <Stack.Screen name="Edit Profile" component={ProfileEditScreen} />
          </Stack.Group>
        </Stack.Navigator>
      </NavigationContainer>  
    );

问题根源与解决方法

核心问题

你创建了navigationRef但没有将它绑定到NavigationContainer上,这导致navigationRef无法正确关联到导航容器,自然无法完成导航操作。另外,auth.onAuthStateChanged的回调可能在导航容器完全挂载前就触发,即使判断了isReady也可能存在时机问题。

修复步骤

  1. 绑定navigationRef到NavigationContainer
    在NavigationContainer中添加ref属性,传入你创建的navigationRef:

    <NavigationContainer ref={navigationRef}>
      {/* 导航器内容 */}
    </NavigationContainer>
    
  2. 优化导航时机
    可以结合useEffect监听navigationRef.isReady的状态,或者利用NavigationContainer的onReady回调来处理初始导航,避免在容器未就绪时触发导航:

    useEffect(() => {
      const subscriber = auth.onAuthStateChanged((_user) => {
        // 等待导航容器就绪后再执行导航
        const handleNavigation = () => {
          if (!_user) {
            navigationRef.navigate('Login');
          } else {
            navigationRef.navigate('CoreTabs', { screen: 'Home' });
          }
        };
    
        if (navigationRef.isReady()) {
          handleNavigation();
        } else {
          // 如果未就绪,监听onReady事件
          const unsubscribe = navigationRef.addListener('ready', handleNavigation);
          return unsubscribe;
        }
      });
    
      return subscriber;
    }, [navigationRef]);
    
  3. 移除不必要的条件渲染(可选)
    你当前在Stack.Group中通过{ user && <Stack.Screen name="CoreTabs" ... /> }来条件渲染屏幕,这可能导致导航时找不到对应路由。建议始终渲染所有屏幕,通过逻辑控制导航而非条件渲染屏幕:

    <Stack.Group>
      <Stack.Screen name="CoreTabs" component={CoreTabs} />
      <Stack.Screen name="Login" component={LoginScreen} />
      <Stack.Screen name="Registration" component={RegistrationScreen}/>
      <Stack.Screen name="Reset Password" component={ResetPasswordScreen}/>
    </Stack.Group>
    

完整修复后的代码示例

import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
import { useEffect } from 'react';

const Stack = createNativeStackNavigator();

export default function App() {
    const navigationRef = useNavigationContainerRef();
    let user = null; // 根据你的实际状态管理逻辑获取user

    useEffect(() => {
      const subscriber = auth.onAuthStateChanged((_user) => {
        user = _user;
        
        const navigate = () => {
          if (!_user) {
            navigationRef.navigate('Login');
          } else {
            navigationRef.navigate('CoreTabs', { screen: 'Home' });
          }
        };

        if (navigationRef.isReady()) {
          navigate();
        } else {
          const readyListener = navigationRef.addListener('ready', navigate);
          return () => readyListener();
        }
      });

      return subscriber;
    }, [navigationRef]);

    return (
      <NavigationContainer ref={navigationRef}>
        <Stack.Navigator>
          <Stack.Group>
            <Stack.Screen name="CoreTabs" component={CoreTabs} />
            <Stack.Screen name="Login" component={LoginScreen} />
            <Stack.Screen name="Registration" component={RegistrationScreen}/>
            <Stack.Screen name="Reset Password" component={ResetPasswordScreen}/>
          </Stack.Group>
          <Stack.Group screenOptions={{ presentation: 'modal' }}>
            <Stack.Screen name="Notifications" component={NotificationsScreen} />
            <Stack.Screen name="Edit Profile" component={ProfileEditScreen} />
          </Stack.Group>
        </Stack.Navigator>
      </NavigationContainer>  
    );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 08:15:44