#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 , но если вам нужны обе платформы, вы можете попробовать собственный модуль