亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

無法清除本機應用程序中的 setInterval

無法清除本機應用程序中的 setInterval

郎朗坤 2023-05-18 09:48:59
我有這個非常簡單的應用程序,我試圖在其中實現倒計時,Start并且Stop功能似乎運行良好但是當我按下時Stop,值seconds在視圖中沒有更新,這是期望的行為但是當我觀察控制臺日志時,它顯示sec我猜不斷變化的價值表明它setInterval仍在運行并且沒有被清除。這是附帶的代碼:import React, { useState, useEffect } from "react";import {  StyleSheet,  Text,  View,  StatusBar,  TouchableOpacity,  Dimensions,} from "react-native";const screen = Dimensions.get("screen");export default function App() {  const [seconds, setSeconds] = useState(4);  const [start, setStartToggle] = useState(true);  let [fun, setFun] = useState(null);  const getRemaining = () => {    const minute = Math.floor(seconds / 60);    const second = seconds - minute * 60;    return formatTime(minute) + ":" + formatTime(second);  };  const formatTime = (time) => {    return ("0" + time).slice(-2);  };  const startTimer = () => {    setStartToggle(false);    console.log("StartTimer");    let sec = seconds;    setFun(      setInterval(() => {        console.log("akak:", sec);        if (sec <= 0) stopTimer();        setSeconds(sec--);      }, 1000)    );  };  const stopTimer = () => {    setStartToggle(true);    console.log("StopTimer");    clearInterval(fun);    setFun(null);  };  return (    <View style={styles.container}>      <StatusBar barStyle="light-content" />      <Text style={styles.timerText}>{getRemaining(seconds)}</Text>      {start ? (        <TouchableOpacity onPress={startTimer} style={styles.button}>          <Text style={styles.buttonText}>Start</Text>        </TouchableOpacity>      ) : (        <TouchableOpacity          onPress={stopTimer}          style={[styles.button, { borderColor: "orange" }]}        >          <Text style={styles.buttonText}>Stop</Text>        </TouchableOpacity>      )}    </View>  );}const styles = StyleSheet.create({  container: {    flex: 1,    backgroundColor: "#07121B",    alignItems: "center",    justifyContent: "center",  },應用行為:https://i.stack.imgur.com/fzdj6.gif 即使在點擊停止后也會顯示輸出:https://i.stack.imgur.com/Ug0aJ.gif
查看完整描述

2 回答

?
白衣非少年

TA貢獻1155條經驗 獲得超0個贊

目前您使用useState掛鉤來存儲區間參考。在每次重新渲染組件時,App狀態fun都會被重置,但不會是對間隔的完全相同的引用。


而是使用useRef鉤子。它可以創建對間隔的引用,該間隔在重新渲染期間不會更改。這意味著引用屬性中的值current將始終完全相同。


最重要的是,使用useEffect鉤子來觀察何時設置或取消設置運行狀態,并根據該狀態啟動和停止計時器。


import React, { useState, useRef, useEffect } from 'react'


export default function App() {

  const [isRunning, setIsRunning] = useState(false);

  const funRef = useRef(null);


  const startTimer = () => {

    if (!isRunning) {

      setIsRunning(true);

    }

  };


  const stopTimer = () {

    if (isRunning && funRef.current !== null) {

      setIsRunning(false);

    }

  };


  useEffect(() => {

    if (isRunning) {

      funRef.current = setInterval(() => { // Save reference to interval.

        // ...

      }, 1000);

    } else {

      clearInterval(funRef.current); // Stop the interval.

    }

  }, [isRunning]);


  // ...

}


查看完整回答
反對 回復 2023-05-18
?
尚方寶劍之說

TA貢獻1788條經驗 獲得超4個贊

在 useEffect 塊中添加間隔計時器,并在每次開始更改時運行此塊:


  useEffect(()=> {

        let timer = null;

    

        if(!start) {

          let sec = seconds;

          timer = setInterval(() => {

            console.log("akak:", sec);

            if (sec <= 0) clearInterval(timer);

            setSeconds(sec--);

          }, 1000);

        } else {

          clearInterval(timer);

       }

   }, [start]);



      const startTimer = () => {

        setStartToggle(false);

      };



      const stopTimer = () => {

        setStartToggle(true);

      };

另外,我建議您使用確切的剩余時間。Javascript 是單線程語言,這個間隔可能超過一秒


編輯:使用確切的時間。


  useEffect(() => {

    let timer = null;


    if (!start) {

      let sec = seconds;

      const startTime = Date.now();

      timer = setInterval(() => {

        const currentTime = Date.now();

        sec = sec - Math.floor((currentTime - startTime) / 1000);

        if (sec < 0) {

          clearInterval(timer);

          setSeconds(0);

        } else {

          setSeconds(sec);

        }

      }, 1000);

    }

  }, [start]);


查看完整回答
反對 回復 2023-05-18
  • 2 回答
  • 0 關注
  • 185 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號