AppState 总是在定时器上触发
AppState Always firing on Timer
我正在后台为 运行 构建一个计时器
我正在使用 React Native 和 Expo 构建应用程序
现在我正在使用的计时器我正试图让它在后台“运行”
为此,我使用 AppState 和一个事件监听器,获取开始时间和经过的时间(在应用程序最小化时详细说明)
然后重新计算经过的时间并将其添加到计时器
Timer中有开始、暂停、重置和完成按钮
我不想开始工作的是,如果单击暂停按钮,经过的时间不能设置为设置状态,无论我在那里放了多少 IF,时间总是会改变
const appState = useRef(AppState.currentState);
const [timerOn, setTimerOn] = useState(false);
const [time, setTime] = useState(0);
const [Paused,isPaused] = useState("");
const getElapsedTime = async () => {
try {
const startTime = await AsyncStorage.getItem("@start_time");
const now = new Date();
return differenceInSeconds(now, Date.parse(startTime));
} catch (err) {
console.warn(err);
}
};
const recordStartTime = async () => {
try {
const now = new Date()
await AsyncStorage.setItem("@start_time", now.toISOString());
} catch (err) {
console.warn(err);
}
};
useEffect(() => {
Timer()
}, []);
function Timer(){
if(Paused == "no"){
AppState.addEventListener("change", handleAppStateChange);
return () => AppState.removeEventListener("change", handleAppStateChange);
}
else{
console.log("eVENT lISTNER")
}
}```
const handleAppStateChange = async (nextAppState) => {
if (appState.current.match(/inactive|background/) &&
nextAppState == "active" && Paused == "no") {
// We just became active again: recalculate elapsed time based
// on what we stored in AsyncStorage when we started.
const elapsed = await getElapsedTime();
// Update the elapsed seconds state
//THE BELOW STATE IS UPDATED TO "ELAPSED" EVENTHOUGH IN THE IF STATEMENT ABOVE SAYS "PAUSED = NO"
setTime(elapsed);
}
else{
console.log("YES")
}
appState.current = nextAppState;
};
useEffect(() => {
let interval = null;
if (timerOn) {
interval = setInterval(() => {
setTime((prevTime) => prevTime + 1);
}, 1000);
} else if (!timerOn) {
clearInterval(interval);
}
return () => clearInterval(interval);
}, [timerOn]);
let MyHour = ("0" + Math.floor((time / 3600))).slice(-2);
let MyMinutes =("0" + Math.floor((time / 60) % 60)).slice(-2);
let MySeconds = ("0" + ((time % 60))).slice(-2);
function TimerBtn(){
isPaused("no")
setTimerOn(true)
recordStartTime()
}
function PauseBtn(){
isPaused("yes")
setTimerOn(false)
}
function ResetBtn(){
setTimerOn(false)
setTime(0)
}
function DoneBtn(){
}
您的问题可能是您无法在侦听器中访问 Paused 的当前状态。阅读此答案 以获得详细说明
要变通,请改用引用 (useRef)。
const [Paused,isPaused] = useState("");
到
const isPaused = useRef(true); // use booleans instead of "yed"/"no"
请记住,要读取和写入引用,您必须将“.current”附加到引用,例如:
isPaused.current = true;
// or
if (isPaused.current) {...}
我正在后台为 运行 构建一个计时器
我正在使用 React Native 和 Expo 构建应用程序
现在我正在使用的计时器我正试图让它在后台“运行”
为此,我使用 AppState 和一个事件监听器,获取开始时间和经过的时间(在应用程序最小化时详细说明) 然后重新计算经过的时间并将其添加到计时器
Timer中有开始、暂停、重置和完成按钮
我不想开始工作的是,如果单击暂停按钮,经过的时间不能设置为设置状态,无论我在那里放了多少 IF,时间总是会改变
const appState = useRef(AppState.currentState);
const [timerOn, setTimerOn] = useState(false);
const [time, setTime] = useState(0);
const [Paused,isPaused] = useState("");
const getElapsedTime = async () => {
try {
const startTime = await AsyncStorage.getItem("@start_time");
const now = new Date();
return differenceInSeconds(now, Date.parse(startTime));
} catch (err) {
console.warn(err);
}
};
const recordStartTime = async () => {
try {
const now = new Date()
await AsyncStorage.setItem("@start_time", now.toISOString());
} catch (err) {
console.warn(err);
}
};
useEffect(() => {
Timer()
}, []);
function Timer(){
if(Paused == "no"){
AppState.addEventListener("change", handleAppStateChange);
return () => AppState.removeEventListener("change", handleAppStateChange);
}
else{
console.log("eVENT lISTNER")
}
}```
const handleAppStateChange = async (nextAppState) => {
if (appState.current.match(/inactive|background/) &&
nextAppState == "active" && Paused == "no") {
// We just became active again: recalculate elapsed time based
// on what we stored in AsyncStorage when we started.
const elapsed = await getElapsedTime();
// Update the elapsed seconds state
//THE BELOW STATE IS UPDATED TO "ELAPSED" EVENTHOUGH IN THE IF STATEMENT ABOVE SAYS "PAUSED = NO"
setTime(elapsed);
}
else{
console.log("YES")
}
appState.current = nextAppState;
};
useEffect(() => {
let interval = null;
if (timerOn) {
interval = setInterval(() => {
setTime((prevTime) => prevTime + 1);
}, 1000);
} else if (!timerOn) {
clearInterval(interval);
}
return () => clearInterval(interval);
}, [timerOn]);
let MyHour = ("0" + Math.floor((time / 3600))).slice(-2);
let MyMinutes =("0" + Math.floor((time / 60) % 60)).slice(-2);
let MySeconds = ("0" + ((time % 60))).slice(-2);
function TimerBtn(){
isPaused("no")
setTimerOn(true)
recordStartTime()
}
function PauseBtn(){
isPaused("yes")
setTimerOn(false)
}
function ResetBtn(){
setTimerOn(false)
setTime(0)
}
function DoneBtn(){
}
您的问题可能是您无法在侦听器中访问 Paused 的当前状态。阅读此答案
const [Paused,isPaused] = useState("");
到
const isPaused = useRef(true); // use booleans instead of "yed"/"no"
请记住,要读取和写入引用,您必须将“.current”附加到引用,例如:
isPaused.current = true;
// or
if (isPaused.current) {...}