登录登出功能异常:登录后首页不显示登出按钮,重启才显示
登录后首页登出按钮不显示,重启应用才正常的解决方案
问题描述
我正在实现登录与登出功能,其他功能均正常,但登录后进入首页时,登出按钮未显示;只有关闭并重新打开应用后,登出按钮才会正常显示。
现有代码
const [isLoggedIn, setIsLoggedIn] = useState(false); useEffect(() => { getTokenData() }, []) const getTokenData = async () => { const token = await AsyncStorage.getItem('access_token'); setIsToken(token) console.warn(token) if (token !== null) { setIsLoggedIn(true) console.warn('logout true') } else { console.warn('logout Success') } }; const handleSignIn = () => { setIsLoggedIn(false) console.warn('sign in') navigation.navigate('SignIn') } const handleLogout = async () => { await AsyncStorage.removeItem('access_token') setIsLoggedIn(false) console.warn('logout') navigation.navigate('HomePage') } {isLoggedIn ? <Btn btnLabel={'Logout'} onPress={handleLogout} />: <Btn btnLabel={'Sign In'} onPress={handleSignIn} /> }
问题原因
当前代码仅在首页组件首次挂载时通过getTokenData从AsyncStorage读取登录状态。登录操作在SignIn页面完成后返回首页时,首页组件并未重新挂载,useEffect不会再次执行,导致isLoggedIn仍保持初始的false值,登出按钮无法显示。只有重启应用后组件重新挂载,才会读取最新的token并更新状态。
解决方案
方案1:监听页面聚焦事件(推荐)
使用React Navigation的useFocusEffect,每次首页被聚焦时重新检查登录状态,确保状态与AsyncStorage同步:
import { useFocusEffect } from '@react-navigation/native'; import React, { useState, useCallback } from 'react'; import AsyncStorage from '@react-native-async-storage/async-storage'; // ...其他组件代码 const [isLoggedIn, setIsLoggedIn] = useState(false); const [isToken, setIsToken] = useState(null); useFocusEffect( useCallback(() => { const checkLoginStatus = async () => { const token = await AsyncStorage.getItem('access_token'); setIsToken(token); setIsLoggedIn(token !== null); }; checkLoginStatus(); }, []) ); // ...handleSignIn、handleLogout等方法保持不变
方案2:登录成功后传递状态参数
在SignIn页面登录成功时,通过导航参数将登录状态传递给首页:
// SignIn页面登录成功后的代码 const handleLoginSuccess = async () => { const token = '获取到的登录token'; await AsyncStorage.setItem('access_token', token); navigation.navigate('HomePage', { isLoggedIn: true }); };
然后在首页监听导航参数变化,更新状态:
import { useEffect, useState } from 'react'; import AsyncStorage from '@react-native-async-storage/async-storage'; // ...其他组件代码 const [isLoggedIn, setIsLoggedIn] = useState(false); const [isToken, setIsToken] = useState(null); useEffect(() => { if (route.params?.isLoggedIn) { setIsLoggedIn(true); } else { getTokenData(); } }, [route.params]); const getTokenData = async () => { const token = await AsyncStorage.getItem('access_token'); setIsToken(token); setIsLoggedIn(token !== null); }; // ...其他方法保持不变
总结
- 方案1更通用,无论从哪个页面回到首页,都会自动检查登录状态,适合大多数场景。
- 方案2更直接,仅在登录后返回首页时更新状态,适合登录流程单一的场景。
内容的提问来源于stack exchange,提问作者Raja Kumar
相关产品推荐
相关产品推荐

