【问题标题】:Disable back button but when tap twice exit app in react native禁用后退按钮,但是当点击两次退出应用程序时反应原生
【发布时间】:2021-07-12 01:55:07
【问题描述】:

我正在尝试创建一个小型反应原生应用程序,并且在该应用程序中,我创建了一些屏幕。在特定屏幕上,我想禁用系统后退按钮,我这样做了,但我想在同一个屏幕上创建一个逻辑,如果用户点击两次,那么应用程序将被关闭。

我的屏幕

import React, {Component, useEffect} from 'react';
import {StyleSheet, Text, View, Button, BackHandler, Alert} from 'react-native';

export default function HomeScreen({navigation}) {
  useEffect(() => {
    BackHandler.addEventListener('hardwareBackPress', () => true);
    return () =>
      BackHandler.removeEventListener('hardwareBackPress', () => true);
  }, []);

  return (
    <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
      <Text>Home Screen</Text>
      <Button
        title="Go to Other Screen"
        onPress={() => navigation.navigate('Employees')}
      />
    </View>
  );
}

但还有一个问题,此代码禁用每个屏幕上的后退按钮。

【问题讨论】:

    标签: javascript android react-native react-navigation


    【解决方案1】:

    对于按下硬件按钮两次退出部分,您可以创建一些状态,增加它,当它等于 2 时使用 Backhandler's exitApp function 退出应用程序。

    如果您只希望Backhandler 事件代码对HomeScreen 组件有效,您可以使用useFocusEffect

    React Navigation 提供了一个钩子,当屏幕聚焦时运行效果并在失焦时清理它

    Source

    function HomeScreen({navigation}) {
      const [backPressedCount, setBackPressedCount] = useState(0);
    
      useFocusEffect(
        useCallback(() => {
          BackHandler.addEventListener('hardwareBackPress', () => {
            setBackPressedCount((backPressedCount) => backPressedCount + 1);
            return true;
          });
          return () =>
            BackHandler.removeEventListener('hardwareBackPress', () => true);
        }, []),
      );
    
      useEffect(() => {
        if (backPressedCount === 2) {
          BackHandler.exitApp();
        }
      }, [backPressedCount]);
    
      return (
        <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
          <Text>Home Screen</Text>
          <Button
            title="Go to Other Screen"
            onPress={() => navigation.navigate('Employees')}
          />
        </View>
      );
    }
    

    【讨论】:

      【解决方案2】:

      基于接受的答案 (Bas van der Linden)。我创建了这个有用的钩子:

      钩子

      const usePreventCloseApp = (onBeforeCloseApp) => {
          const [backPressedCount, setBackPressedCount] = useState(0);
      
          useFocusEffect(
              useCallback(() => {
                  const sub = BackHandler.addEventListener(
                      'hardwareBackPress',
                      () => {
                          if (onBeforeCloseApp) {
                              onBeforeCloseApp(() => setBackPressedCount(2));
                          } else {
                              setBackPressedCount((pre) => {
                                  if (pre === 0) {
                                      ToastAndroid.show('Press again to exit', 1000);
                                      setTimeout(() => setBackPressedCount(0), 1000);
                                  }
                                  return pre + 1;
                              });
                          }
                          return true;
                      },
                  );
                  return sub.remove;
              }, [onBeforeCloseApp]),
          );
      
          useEffect(() => {
              if (backPressedCount === 2) {
                  BackHandler.exitApp();
              }
          }, [backPressedCount]);
      
          return {
              closeApp: () => setBackPressedCount(2),
          };
      };
      

      用法

      显示默认吐司“再次按下退出”

      const { closeApp } = usePreventCloseApp();
      

      带有自定义回调

      usePreventCloseApp((closeApp) => {
           Alert.alert('Close App', 'Are you sure want to close app?', [
               {
                   text: 'Cancel',
                   style: 'cancel',
               },
               {
                   text: 'Close App',
                   style: 'destructive',
                   onPress: closeApp,
               },
           ]);
       });
      

      【讨论】:

        猜你喜欢
        • 2019-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-29
        • 1970-01-01
        • 2014-01-02
        • 1970-01-01
        相关资源
        最近更新 更多