AppState event persists across all app screens even when cleaned

huangapple go评论81阅读模式
英文:

AppState event persists across all app screens even when cleaned

问题

我使用AppState API监听器来在应用程序从后台切换到活动状态时运行函数。我在useEffect清理中删除了它,但它仍然在其他屏幕上被调用,就好像从未被清理过。

const MyRoute = ({ navigation, route }) => {
  const appStateRef = useRef(AppState.currentState);

  useEffect(() => {
    getUserData();

    function updateRouteData(nextAppState) {
      if (appStateRef.current.match(/inactive|background/) && nextAppState === 'active') {
        getRoutes(); // <--
      }

      appStateRef.current = nextAppState;
    }

    AppState.addEventListener('change', updateRouteData);

    return () => {
      AppState.removeEventListener('change', updateRouteData);
    };
  }, []);

  // ...
}

AppState事件监听器仍然存在于其他屏幕上。

react-native版本: "0.64.4"

英文:

I use the AppState API listener to run a function when the app comes from background to active state. I remove it on the useEffect cleanup, but it is still being called on the other screens like it was never cleaned.

const MyRoute = ({ navigation, route }) => {
  const appStateRef = useRef(AppState.currentState);

  useEffect(() => {
    getUserData();

    function updateRouteData(nextAppState) {
      if (appStateRef.current.match(/inactive|background/) && nextAppState === 'active') {
        getRoutes(); // <--
      }

      appStateRef.current = nextAppState;
    }

    AppState.addEventListener('change', updateRouteData);

    return () => {
      AppState.removeEventListener('change', updateRouteData);
    };
  }, []);

  // ...
}

The AppState event listener persists on the other screens.

react-native: "0.64.4"

答案1

得分: 0

将事件监听器存储在变量中,然后移除它。

const appStateListener = AppState.addEventListener();

appStateListener?.remove();
英文:

Get the event listener in a variable and then remove it.

const appStateListener = AppState.addEventListener()

appStateListener?.remove();

答案2

得分: 0

I found a solution.

Instead of calling the appstate logic inside a useEffect, I call it with the useFocusEffect from the react navigation. When leaving the screen you can trigger a cleanup function to remove the listener.

I created a custom hook to use it on my app.

const useAppStateListener = (callback) => {
  const appStateRef = useRef(AppState.currentState);

  useFocusEffect(
    useCallback(() => {
      async function updateRouteData(nextAppState) {
        if (appStateRef.current.match(/inactive|background/) && nextAppState === 'active') {
          await callback();
        }

        appStateRef.current = nextAppState;
      }

      AppState.addEventListener('change', updateRouteData);

      return () => {
        AppState.removeEventListener('change', updateRouteData);
      };
    }, [callback]),
  );

  return appStateRef;
};
英文:

I found a solution.

Instead of calling the appstate logic inside a useEffect, I call it with the useFocusEffect from the react navigation. When leaving the screen you can trigger a cleanup function to remove the listener.

I created a custom hook to use it on my app.

const useAppStateListener = (callback) => {
  const appStateRef = useRef(AppState.currentState);

  useFocusEffect(
    useCallback(() => {
      async function updateRouteData(nextAppState) {
        if (appStateRef.current.match(/inactive|background/) && nextAppState === 'active') {
          await callback();
        }

        appStateRef.current = nextAppState;
      }

      AppState.addEventListener('change', updateRouteData);

      return () => {
        AppState.removeEventListener('change', updateRouteData);
      };
    }, [callback]),
  );

  return appStateRef;
};

huangapple
  • 本文由 发表于 2023年5月25日 04:25:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76327185.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定