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

React Native登录后无法自动跳转至Main页面问题求助

问题分析
  1. 登录成功后需刷新才能进入Main页面:App.js仅在初始化时读取一次AsyncStorage中的token,登录成功后更新了token但未同步更新isLoggedIn状态,导致导航栈仍维持未登录时的配置(仅包含Login、Register等页面)。
  2. 报错The action 'NAVIGATE' with payload {"name":"Main"} was not handled by any navigator:当前导航栈中未注册Main页面,直接调用navigate('Main')会找不到对应路由。
解决方案(推荐用Context全局管理登录状态)

步骤1:创建AuthContext管理登录状态

新建AuthContext.js文件:

import React, { createContext, useContext, useState, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';

const AuthContext = createContext();

export function AuthProvider({ children }) {
  const [isLoggedIn, setIsLoggedIn] = useState(null);

  // 初始化检查token
  useEffect(() => {
    const checkToken = async () => {
      const token = await AsyncStorage.getItem('token');
      setIsLoggedIn(!!token);
    };
    checkToken();
  }, []);

  // 登录方法:存token并更新状态
  const login = async (token) => {
    await AsyncStorage.setItem('token', token);
    setIsLoggedIn(true);
  };

  // 可选登出方法
  const logout = async () => {
    await AsyncStorage.removeItem('token');
    setIsLoggedIn(false);
  };

  return (
    <AuthContext.Provider value={{ isLoggedIn, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  return useContext(AuthContext);
}

步骤2:修改App.js使用AuthProvider

import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import Login from './screens/Login';
import LoadingScreen from './components/LoadingScreen';
import Register from './screens/Register';
import Verification from './screens/Verification';
import Main from './screens/Main';
import { AuthProvider, useAuth } from './AuthContext';

const Stack = createNativeStackNavigator();

// 抽离导航栈组件,消费AuthContext
function NavigationStack() {
  const { isLoggedIn } = useAuth();

  return (
    <Stack.Navigator screenOptions={{ headerShown: false }}>
      {/* 加载状态:等待token检查完成 */}
      {isLoggedIn === null ? (
        <Stack.Screen name='Loading' component={LoadingScreen} />
      ) : isLoggedIn ? (
        {/* 已登录:显示Main页面 */}
        <Stack.Screen name='Main' component={Main} />
      ) : (
        {/* 未登录:显示登录相关页面 */}
        <>
          <Stack.Screen name='Login' component={Login} />
          <Stack.Screen name='Register' component={Register} />
          <Stack.Screen name='verification' component={Verification} />
        </>
      )}
    </Stack.Navigator>
  );
}

function App() {
  return (
    <AuthProvider>
      <NavigationContainer>
        <NavigationStack />
      </NavigationContainer>
    </AuthProvider>
  );
}

export default App;

步骤3:修改Login.js调用AuthContext的登录方法

import { useNavigation } from '@react-navigation/native';
import { StatusBar } from 'expo-status-bar';
import axios from 'axios';
import React, { useState } from 'react';
import { useAuth } from '../AuthContext'; // 导入useAuth

import {
  StyleSheet,
  Text,
  View,
  Image,
  TextInput,
  Button,
  TouchableOpacity,
} from 'react-native';

export default function Login() {
  const navigation = useNavigation();
  const { login } = useAuth(); // 获取全局登录方法
  const [fData, setfData] = useState({
    email: '',
    password: '',
  });

  const handleSubmit = async () => {
    try {
      const response = await axios.post(
        '<backend_url>/login',
        fData
      );
      console.log(response.data);
      await login(response.data.token); // 调用登录方法,自动更新全局状态
    } catch (error) {
      if (error.response && error.response.status === 422) {
        alert('Invalid Credentials');
      } else {
        alert('An error occurred. Please try again later.');
      }
    }
  };

  // 其余UI代码保持不变
  return (
    <View style={styles.container}>
      <Image style={styles.image} source={require('../assets/BU.png')} />

      <StatusBar style='auto' />

      <View style={styles.inputView}>
        <TextInput
          style={styles.TextInput}
          placeholder='Enter your Email.'
          placeholderTextColor='#003f5c'
          autoCapitalize='none'
          autoCorrect={false}
          keyboardType='email-address'
          value={fData.email}
          onChangeText={(text) => setfData({ ...fData, email: text })}
        />
      </View>

      <View style={styles.inputView}>
        <TextInput
          style={styles.TextInput}
          placeholder='Enter your password.'
          placeholderTextColor='#003f5c'
          secureTextEntry={true}
          autoCapitalize='none'
          autoCorrect={false}
          value={fData.password}
          onChangeText={(text) => setfData({ ...fData, password: text })}
        />
      </View>

      <TouchableOpacity onPress={() => navigation.navigate('Register')}>
        <Text style={styles.forgot_button}>Not a Member yet? Register </Text>
      </TouchableOpacity>

      <Button title='Login' onPress={() => handleSubmit()} />
    </View>
  );
}
原理说明

通过AuthContext将登录状态全局共享,登录成功后调用login方法会自动更新isLoggedIn状态,触发NavigationStack重新渲染,自动切换到包含Main页面的导航栈;新增Loading页面避免初始化时的路由闪烁,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:47:05