Закройте действие React Native apps / dispatch redux при работе в фоновом режиме

#react-native #react-redux #react-hooks

Вопрос:

Я хочу создать функцию внутри своих компонентов, которая определяет, когда приложение находится в фоновом режиме в течение 30 секунд, я хочу отправить действие выхода из системы или закрыть приложения. возможно ли это, если мы сделаем это в react native?

Я использую крючки

Спасибо,

обновление : Я использую решение wowandy, но дело в том, что если пользователь закроет приложения менее чем на 10 секунд, а затем снова откроет приложение, команда отправки все равно будет выполнена через 30 секунд. есть ли какой-нибудь способ отменить тайм-аут ?

  useEffect(() => {
    let timeout;

    const subscription = AppState.addEventListener('change', (nextAppState) => {
      clearTimeout(timeout);


      if (appState.current === 'background') {
        timeout = setTimeout(() => dispatch(removeDataLogin()), 30000);
      }

      appState.current = nextAppState;
    });

    return () => {
      subscription.remove();
      clearTimeout(timeout);
    };
  }, []);
 

Обновление 3
Поэтому я попытался использовать решение Майкла Бахля, как описано ниже. это отлично работает с меткой времени.

 useEffect(() => {
    let start;
    let end;
    const subscription = AppState.addEventListener("change", nextAppState => {
      if (
        appState.current.match(/inactive|background/) amp;amp;
        nextAppState === "active"
      ) {
        end = new Date()
        let ms = moment(end).diff(moment(start))
        if (Number(ms) >= 30000) {
          dispatch(removeDataLogin())
        } else {
        }
      } else {
        start = new Date()
        console.log('start diff :', start)
      }
      appState.current = nextAppState;
      setAppStateVisible(appState.current);
      console.log("AppState", appState.current);
    });

    return () => {
      subscription.remove();
    };
  }, []);
 

обновление 3 Я использую решение Майкла Бахля, поэтому я создал метку времени, которая проверяет разницу между неактивными и активными экранами, а затем отправляет действие redux

 useEffect(() => {
    let start;
    let end;
    const subscription = AppState.addEventListener("change", nextAppState => {
      if (
        appState.current.match(/inactive|background/) amp;amp;
        nextAppState === "active"
      ) {
        console.log('end =====')
        console.log('start diff == ', start)
        end = new Date()
        console.log('end diff ===', end)
        let ms = moment(end).diff(moment(start))
        console.log('different : ', ms)
        console.log(typeof ms)
        if (Number(ms) >= 30000) {
          console.log('harusnya logout')
          dispatch(removeDataLogin())
        } else {
          console.log(ms, 'masuk sini')
        }
      } else {
        start = new Date()
        console.log('start diff :', start)
      }


      appState.current = nextAppState;
      setAppStateVisible(appState.current);
      console.log("AppState", appState.current);
    });

    return () => {
      subscription.remove();
    };
  }, []);
 

Комментарии:

1. Я бы посоветовал сохранить отметку времени, когда приложение перешло в фоновый режим, а когда оно вернется на передний план, проверьте, не истекло ли 30 секунд. В зависимости от того, истекли ли 30 секунд, откройте экран входа в систему или сохраните последний открытый экран.

Ответ №1:

Вы можете обрабатывать состояние приложения с помощью AppState и закрывать его с помощью BackHandler

См. Пример:

 import React, {useRef, useEffect} from 'react';
import {AppState, BackHandler} from 'react-native';

const App = () => {
  const appState = useRef(AppState.currentState);

  useEffect(() => {
    let timeout;

    const subscription = AppState.addEventListener('change', (nextAppState) => {
      clearTimeout(timeout);

      if (appState.current === 'background') {
        timeout = setTimeout(() => BackHandler.exitApp(), 30000);
      }

      appState.current = nextAppState;
    });

    return () => {
      subscription.remove();
      clearTimeout(timeout);
    };
  }, []);

  // TODO

  return /* TODO */;
};

 

Комментарии:

1. Спасибо за ответ, я пробовал это, но вместо того, чтобы использовать удар слева. я отправляю подобное действие , дело в том, что оно работает нормально, но если приложения будут работать в фоновом режиме в течение 10 секунд, и я снова открою его, команда отправки будет выполнена через определенное время. есть ли какой-либо способ отменить тайм-аут, когда приложение находится на переднем плане ?

2. обновление: действие отправки все еще вызывается на переднем плане через 30 секунд. Есть ли способ отменить тайм-аут?

3. @QrQr если вы ориентируетесь только на Android , то вы можете попробовать безголовый js , но если вам нужны обе платформы, вы можете попробовать собственный модуль