[英]Using react hooks, how would you write an event listener dependent on state that does not need to be added and removed every time the state changes?
The code below shows a working, but inefficient implementation of an Android BackHandler
within React Native to have the app exit after two presses in two seconds.下面的代码显示了在 React Native 中 Android
BackHandler
的有效但低效的实现,使应用程序在两秒内按下两次后退出。 This is implemented using React hooks within the main functional component of the app.这是在应用程序的主要功能组件中使用 React hooks 实现的。
However, due to dependency on a state variable recentlyPressedHardwareBack
, the useEffect
hook will cleanup then run each time the state changes, causing the BackHandler
event listener to be detached and re-attached whenever the back button is pressed.但是,由于依赖于 state 变量
recentlyPressedHardwareBack
, useEffect
挂钩将在每次 state 更改时进行清理然后运行,从而导致BackHandler
事件侦听器在按下后退按钮时分离并重新附加。 How do you set up this event listener just once without constant creation and deletion, while allowing it to access a changing component state?如何在不不断创建和删除的情况下仅设置一次此事件侦听器,同时允许它访问不断变化的组件 state?
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]);
You could use useRef for this.您可以为此使用 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();
}, [])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.