React Native登录后导航未刷新跳转,重启才显示主页如何解决?
你当前的代码有两个核心问题导致登录成功后无法自动跳转:
- App组件的
isSignedIn状态仅在初始化时读取一次AsyncStorage,登录成功后更新了本地存储但没有同步更新这个状态,App不会触发重渲染切换导航栈 - 你声明了两个独立的
NavigationContainer,不符合React Navigation的使用规范,正常全局只需要一个容器即可
第一步:新增全局登录状态管理
用React内置的Context来全局共享登录状态,新建一个AuthContext.js文件,内容如下:
import { createContext, useContext } from 'react'; export const AuthContext = createContext(); export const useAuth = () => useContext(AuthContext);
第二步:修改App.js代码
修改后代码如下:
import { useState, useEffect } from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { StatusBar } from 'react-native'; import { AuthContext } from './AuthContext'; // 下面替换成你自己的页面引入路径 import LobbyScreen from './LobbyScreen'; import LogActivityScreen from './LogActivityScreen'; import PreviousLogsScreen from './PreviousLogsScreen'; import AnnouncementsScreen from './AnnouncementsScreen'; import GuidesScreen from './GuidesScreen'; import CreditsScreen from './CreditsScreen'; import LoginScreen from './LoginScreen'; import RegisterScreen from './RegisterScreen'; const Stack = createStackNavigator(); function App() { const [isSignedIn, setIsSignedIn] = useState(null); useEffect(() => { // 初始化读取本地token async function getData(){ try { const value = await AsyncStorage.getItem('token') setIsSignedIn(!!value); // 转成布尔值更清晰,有token为true,无则为false } catch(e) { console.log(e) setIsSignedIn(false); } } getData() }, []) // 初始加载时返回空/加载页,避免闪屏 if (isSignedIn === null) { return null; // 也可以替换成你自定义的Loading组件 } return ( <AuthContext.Provider value={{ isSignedIn, setIsSignedIn }}> <NavigationContainer> <StatusBar backgroundColor="#ffe6d9"/> <Stack.Navigator> {isSignedIn ? ( // 已登录页面栈 <> <Stack.Screen name="LobbyScreen" component={LobbyScreen} options={{header: () => null}}/> <Stack.Screen name="LogActivityScreen" component={LogActivityScreen} options={{header: () => null}}/> <Stack.Screen name="PreviousLogsScreen" component={PreviousLogsScreen} options={{header: () => null}}/> <Stack.Screen name="AnnouncementsScreen" component={AnnouncementsScreen} options={{header: () => null}}/> <Stack.Screen name="GuidesScreen" component={GuidesScreen} options={{header: () => null}}/> <Stack.Screen name="CreditsScreen" component={CreditsScreen} options={{header: () => null}}/> </> ) : ( // 未登录页面栈 <> <Stack.Screen name="LoginScreen" component={LoginScreen} options={{header: () => null}}/> <Stack.Screen name="RegisterScreen" component={RegisterScreen} options={{header: () => null}}/> </> )} </Stack.Navigator> </NavigationContainer> </AuthContext.Provider> ); } export default App;
第三步:修改LoginScreen.js代码
修改storeData方法,登录成功后更新全局状态:
import { useAuth } from './AuthContext'; // 引入刚才定义的useAuth钩子 export default function LoginScreen() { const [username, setUsername] = useState('username'); const [password, setPassword] = useState('password'); const navigation = useNavigation(); const { setIsSignedIn } = useAuth(); // 获取全局更新登录状态的方法 const storeData = async (value) => { try { if (value == undefined) { alert('Invalid Login: Please Try Again') } else { await AsyncStorage.setItem('token', String(value)) console.log('Data successfully saved') setIsSignedIn(true); // 更新全局状态,App会自动切换到主页栈 } } catch (e) { console.log(e) } } // 其余代码和你原有逻辑完全一致,保留原有的SubmitLogin方法和页面布局即可 // ... }
如果项目还没安装AsyncStorage,执行npm i @react-native-async-storage/async-storage安装即可。
内容的提问来源于stack exchange,提问作者luis john
相关产品推荐
相关产品推荐

