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

React Native认证后动态导航问题:登录/注册跳转不同页面

解决React Navigation认证后动态跳转问题

别再用条件渲染屏幕的方式了,这种写法不仅限制跳转灵活性,还容易触发组件挂载问题。按照下面的步骤改,就能实现注册跳OnBoarding、登录跳Home的需求:

1. 重构导航结构:移除条件渲染

把所有屏幕都注册到导航栈里,不管认证状态,后续用路由守卫控制访问权限:

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

function AppNavigator({ user }) {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="LoadingScreen" headerMode='none'>
        {/* 通用加载页 */}
        <Stack.Screen name='LoadingScreen' component={LoadingScreen} />
        {/* 未认证页面 */}
        <Stack.Screen name='Signup' component={Signup} />
        <Stack.Screen name='Login' component={Login} />
        {/* 已认证页面 */}
        <Stack.Screen name='Home' component={Home} />
        <Stack.Screen name='OnBoarding' component={OnBoarding} />
        <Stack.Screen name='Preferences' component={Preferences} />
        <Stack.Screen name='TabNav' component={TabNav} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

2. 标记用户类型:区分登录/注册用户

在登录、注册成功时,给用户对象加个isNewUser标记,用来判断跳转目标:

注册组件(Signup)

const handleSignup = async () => {
  // 执行注册接口请求
  const userData = await authService.signup(email, password);
  // 标记为新用户
  await setUser({ ...userData, isNewUser: true });
};

登录组件(Login)

const handleLogin = async () => {
  // 执行登录接口请求
  const userData = await authService.login(email, password);
  // 标记为老用户
  await setUser({ ...userData, isNewUser: false });
};

3. 监听用户状态,动态跳转

在LoadingScreen里监听user状态变化,用navigation.replace跳转(用replace避免返回登录/注册页):

import { ActivityIndicator, View } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { useEffect } from 'react';

function LoadingScreen({ user }) {
  const navigation = useNavigation();

  useEffect(() => {
    if (!user) {
      // 未登录,跳转到登录页
      navigation.replace('Login');
      return;
    }

    // 根据用户类型跳转
    if (user.isNewUser) {
      navigation.replace('OnBoarding');
    } else {
      navigation.replace('Home');
    }
  }, [user, navigation]);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <ActivityIndicator size="large" />
    </View>
  );
}

4. 加路由守卫,控制页面访问权限

防止未认证用户直接访问已认证页面,或者已认证用户回退到登录/注册页:

// 在AppNavigator里添加全局路由监听
import { useNavigationContainerRef } from '@react-navigation/native';
import { useEffect } from 'react';

function AppNavigator({ user }) {
  const navigationRef = useNavigationContainerRef();

  useEffect(() => {
    const unsubscribe = navigationRef.addListener('state', () => {
      const currentRoute = navigationRef.getCurrentRoute()?.name;
      if (!currentRoute) return;

      const isAuthenticated = !!user;
      const authRoutes = ['Home', 'OnBoarding', 'Preferences', 'TabNav'];
      const unAuthRoutes = ['Signup', 'Login'];

      // 未认证用户访问已认证页面,强制跳登录
      if (!isAuthenticated && authRoutes.includes(currentRoute)) {
        navigationRef.replace('Login');
      }

      // 已认证用户访问未认证页面,跳对应目标
      if (isAuthenticated && unAuthRoutes.includes(currentRoute)) {
        user.isNewUser ? navigationRef.replace('OnBoarding') : navigationRef.replace('Home');
      }
    });

    return unsubscribe;
  }, [user, navigationRef]);

  // ...导航结构
}

这样改完,既能实现动态跳转需求,又符合React Navigation的最佳实践,不会出现组件挂载问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 21:33:10