下面的代码显示了在 React Native 中的 Android BackHandler
的一个有效但低效的实现,以使应用程序在两秒内按两次后退出。这是在应用程序的主要功能组件中使用 React hooks 实现的。
然而,由于依赖于状态变量 recentlyPressedHardwareBack
,useEffect
挂钩将在每次状态更改时进行清理然后运行,从而导致每次按下后退按钮时分离并重新附加 BackHandler
事件侦听器。如何在不不断创建和删除的情况下只设置一次此事件侦听器,同时允许它访问不断变化的组件状态?
const [recentlyPressedHardwareBack, setRecentlyPressedHardwareBack] =
useState(false);
useEffect(() => {
const backHandler = BackHandler.addEventListener(
'hardwareBackPress',
() => {
// Exit app if user pressed the button within last 2 seconds.
if (recentlyPressedHardwareBack) {
return false;
}
ToastAndroid.show(
'Press back again to exit the app',
ToastAndroid.SHORT,
);
setRecentlyPressedHardwareBack(true);
// Toast shows for approx 2 seconds, so this is the valid period for exiting the app.
setTimeout(() => {
setRecentlyPressedHardwareBack(false);
}, 2000);
// Don't exit yet.
return true;
},
);
return () => backHandler.remove();
}, [recentlyPressedHardwareBack]);
回答1
您可以为此使用 useRef。
const recentlyPressedHardwareBackRef = useRef(false);
useEffect(() => {
const backHandler = BackHandler.addEventListener(
'hardwareBackPress',
() => {
// Exit app if user pressed the button within last 2 seconds.
if (recentlyPressedHardwareBackRef.current) {
return false;
}
ToastAndroid.show(
'Press back again to exit the app',
ToastAndroid.SHORT,
);
recentlyPressedHardwareBackRef.current = true;
// Toast shows for approx 2 seconds, so this is the valid period for exiting the app.
setTimeout(() => {
recentlyPressedHardwareBackRef.current = false;
}, 2000);
// Don't exit yet.
return true;
},
);
return () => backHandler.remove();
}, [])