【问题标题】:AppState Always firing on TimerAppState 总是在 Timer 上触发
【发布时间】:2021-11-26 09:56:53
【问题描述】:

我正在构建一个在后台运行的计时器

我正在使用 React Native 和 Expo 来构建应用程序

现在我正在使用的计时器正试图让它在后台“运行”

为此,我使用 AppState 和事件侦听器,获取开始时间和经过时间(在应用程序最小化时 Elabsed) 然后重新计算经过的时间并将其添加到计时器中

在定时器中有开始、暂停、重置和完成按钮

想让我不开始工作的是,如果单击暂停按钮,则不能将经过的时间设置为 setstate,并且无论我在那里放了多少个 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(){


}

【问题讨论】:

    标签: react-native expo


    【解决方案1】:

    您的问题可能是您无法在侦听器中访问 Paused 的当前状态。阅读此答案here 以获得详细说明 要解决此问题,请改用引用 (useRef)。

    const [Paused,isPaused] = useState("");
    

    const isPaused = useRef(true); // use booleans instead of "yed"/"no"
    

    记住要读取和写入引用,您必须将“.current”附加到引用中,例如:

    isPaused.current = true;
    // or
    if (isPaused.current) {...} 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-07
      • 2016-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多