react-native - 使用 react 钩子,您将如何编写一个依赖于状态的事件侦听器,而无需在每次状态更改时添加和删除?

下面的代码显示了在 React Native 中的 Android BackHandler 的一个有效但低效的实现,以使应用程序在两秒内按两次后退出。这是在应用程序的主要功能组件中使用 React hooks 实现的。

然而,由于依赖于状态变量 recentlyPressedHardwareBackuseEffect 挂钩将在每次状态更改时进行清理然后运行,从而导致每次按下后退按钮时分离并重新附加 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();
}, [])

相似文章