禁用后退按钮但是当点击两次退出应用程序时反应本机
Disable back button but when tap twice exit app in react native
我正在尝试创建一个小型 React 本机应用程序,在该应用程序中,我创建了一些屏幕。在特定屏幕上,我想禁用系统后退按钮并且我这样做了,但我想在同一屏幕上创建一个逻辑,如果用户点击两次,则应用程序将关闭。
我的屏幕
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>
);
}
但是还有一个问题,这段代码在每个屏幕上都禁用了后退按钮。
对于按两次硬件按钮退出部分,您可以创建一些状态,递增它,当它等于 2
时使用 Backhandler
's exitApp
function 退出应用程序。
如果您只想为 HomeScreen
组件激活 Backhandler
事件代码,您可以使用 useFocusEffect
React Navigation provides a hook that runs an effect when the screen comes into focus and cleans it up when it goes out of focus
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>
);
}
基于已接受的答案 (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),
};
};
用法
显示默认 toast“再次按下退出”
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,
},
]);
});
我正在尝试创建一个小型 React 本机应用程序,在该应用程序中,我创建了一些屏幕。在特定屏幕上,我想禁用系统后退按钮并且我这样做了,但我想在同一屏幕上创建一个逻辑,如果用户点击两次,则应用程序将关闭。
我的屏幕
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>
);
}
但是还有一个问题,这段代码在每个屏幕上都禁用了后退按钮。
对于按两次硬件按钮退出部分,您可以创建一些状态,递增它,当它等于 2
时使用 Backhandler
's exitApp
function 退出应用程序。
如果您只想为 HomeScreen
组件激活 Backhandler
事件代码,您可以使用 useFocusEffect
React Navigation provides a hook that runs an effect when the screen comes into focus and cleans it up when it goes out of focus
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>
);
}
基于已接受的答案 (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),
};
};
用法
显示默认 toast“再次按下退出”
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,
},
]);
});