React Native认证后动态导航问题:登录/注册跳转不同页面
别再用条件渲染屏幕的方式了,这种写法不仅限制跳转灵活性,还容易触发组件挂载问题。按照下面的步骤改,就能实现注册跳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
相关产品推荐
相关产品推荐

