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

如何使用useEffect实现注销?Alert弹窗重复触发问题排查

注销页面弹窗重复触发问题解决

原代码与问题现象

// 注销页面

import {Alert} from 'react-native';
import {useEffect} from 'react';
import {useIsFocused} from '@react-navigation/native';
const Logout = props => {
  const Logout1 = () => {
    const isFocused = useIsFocused();
    Alert.alert('Logout', 'Are you sure you want to logout?', [
      {
        text: 'Cancel',
        onPress: () =>
          props.navigation.navigate(
            'Tabs',
            {
              screen: 'HomeScreen',
            },
          ),
      },
      {text: 'Yes', onPress: () => props.navigation.navigate('Login')},
    ]);
  };
  useEffect(() => {}, [useIsFocused(), Logout1()]);
};
export default Logout;

问题:
期望Alert.alert仅触发1次,但实际触发了2次:

  • 点击底部Tab栏的Logout按钮时
  • 点击Cancel按钮并跳转到其他页面时,弹窗再次弹出

问题原因

  1. Hook调用违反规则:useIsFocused()是React Hook,必须直接在组件顶层调用,不能嵌套在Logout1这类普通函数内部。
  2. useEffect依赖数组错误:依赖数组里直接执行Logout1(),会导致组件每次渲染、useIsFocused()返回值变化时都触发弹窗逻辑。
  3. 无重复触发控制:没有状态标记弹窗是否已显示,页面焦点变化时会重复执行弹窗代码。

修正后的代码

import {Alert} from 'react-native';
import {useEffect, useState} from 'react';
import {useIsFocused} from '@react-navigation/native';

const Logout = props => {
  const isFocused = useIsFocused();
  const [hasShownAlert, setHasShownAlert] = useState(false);

  const showLogoutAlert = () => {
    Alert.alert('Logout', 'Are you sure you want to logout?', [
      {
        text: 'Cancel',
        onPress: () => {
          props.navigation.navigate('Tabs', {screen: 'HomeScreen'});
          setHasShownAlert(false);
        },
      },
      {
        text: 'Yes',
        onPress: () => {
          props.navigation.navigate('Login');
          setHasShownAlert(false);
        },
      },
    ]);
  };

  useEffect(() => {
    if (isFocused && !hasShownAlert) {
      setHasShownAlert(true);
      showLogoutAlert();
    }
  }, [isFocused, hasShownAlert]);

  return null;
};

export default Logout;

修正说明

  • 组件顶层调用useIsFocused(),符合Hook规则的同时正确获取页面焦点状态。
  • 新增hasShownAlert状态,标记弹窗是否已显示,避免焦点变化时重复触发。
  • useEffect仅在页面获取焦点且未弹窗过时执行弹窗逻辑,确保单次触发。
  • 点击弹窗按钮后重置hasShownAlert,保证下次进入注销页面时能正常触发弹窗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:01:00