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

React Native登录鉴权条件判断异常:点击需两次才跳转

React Native登录鉴权跳转二次点击问题解决方案

问题背景

在React Native中实现用户登录鉴权逻辑:从后端获取token并存入SecureStore,点击图标时根据token是否存在跳转至注册/登录页或个人资料页。目前SecureStore中的token值能正确更新,但点击跳转时需第二次点击才能导航至对应页面,尝试过useEffect但认为其仅在组件渲染时更新值,无法解决点击时的问题。

现有代码

MusicScreen跳转逻辑

const MusicScreen = () => {

    //Constante de navegación
    const navigation = useNavigation();
    //Estado para sacar el token de asyncStorage
    const [token, setToken] = useState(null);
    //Saca el token y lo almacena temporalmente en setToken

        const getToken = async () => {
          try {
            const storedToken = await SecureStore.getItemAsync('token');
            setToken(storedToken);
            console.log(storedToken)
          } catch (error) {
            console.error('Error al obtener el token:', error);
          }
        };
    

    const handleIconPress = () => {
        getToken();
        if (token === null) {
          navigation.navigate('Register');
        } else {
          navigation.navigate('Profile');
        }
      };


    return (
        <View >
            <LinearGradient 
            colors={['#c501e2','#fe0ab7','#ae3dff','transparent']} style={styles.Background}>
            <TouchableOpacity onPress={handleIconPress} style={styles.touchable}>
                <Image source={require('../files-logos/D-Corchea.png')} style={styles.image}/>
            </TouchableOpacity>
      </LinearGradient>
        </View>     
  )};

ProfileScreen登出逻辑

const logout = async() => {
    try{
        await SecureStore.deleteItemAsync('token');
        const storedToken = await SecureStore.getItemAsync('token');
        console.log(storedToken);
    }catch(e){
        console.log('Error trying to delete de token:', e);
    }
}
const ProfileScreen= () => {
    const navigation = useNavigation();
    return (
        <View>
            <Background1/>
        <Text style={{fontWeight:'bold',}}>THis is the profile screen</Text>
        <Button title='logout' onPress={()=>{
            logout();
            navigation.navigate('Register');
        }} />
        </View>
    )};

export default ProfileScreen;

问题原因

handleIconPress中调用的getToken是异步函数,而setToken更新React状态属于异步操作。第一次点击时,getToken还未完成SecureStore的读取操作,token状态仍为旧值,导致判断逻辑基于旧值执行;第二次点击时状态已更新,判断才会生效。

解决方案

无需依赖组件状态token执行跳转判断,直接在异步读取流程中拿到最新token后立即处理导航,或者将handleIconPress改为异步函数,确保读取完成后再执行判断(更推荐前者,减少不必要的状态依赖)。

修改后的MusicScreen代码

const MusicScreen = () => {
    const navigation = useNavigation();

    const handleIconPress = async () => {
      try {
        const storedToken = await SecureStore.getItemAsync('token');
        console.log(storedToken);
        // 直接用刚获取的最新token判断跳转
        if (storedToken === null) {
          navigation.navigate('Register');
        } else {
          navigation.navigate('Profile');
        }
      } catch (error) {
        console.error('Error al obtener el token:', error);
        // 出错时默认跳注册页或给出提示
        navigation.navigate('Register');
      }
    };

    return (
        <View >
            <LinearGradient 
            colors={['#c501e2','#fe0ab7','#ae3dff','transparent']} style={styles.Background}>
            <TouchableOpacity onPress={handleIconPress} style={styles.touchable}>
                <Image source={require('../files-logos/D-Corchea.png')} style={styles.image}/>
            </TouchableOpacity>
      </LinearGradient>
        </View>     
  )};

补充说明

如果token状态还需在组件其他场景使用,可保留setToken,但跳转逻辑仍需基于刚读取的storedToken:

const MusicScreen = () => {
    const navigation = useNavigation();
    const [token, setToken] = useState(null);

    const handleIconPress = async () => {
      try {
        const storedToken = await SecureStore.getItemAsync('token');
        setToken(storedToken);
        console.log(storedToken);
        // 用最新读取的storedToken判断,而非state中的token
        if (storedToken === null) {
          navigation.navigate('Register');
        } else {
          navigation.navigate('Profile');
        }
      } catch (error) {
        console.error('Error al obtener el token:', error);
        navigation.navigate('Register');
      }
    };

    return (
        // 原有UI代码
    )};

修改后,第一次点击即可获取最新token并执行正确的导航逻辑,无需二次点击。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:07:46