3 votes

React Hooks Clock - Effacer SetInterval après un certain temps

J'ai une fonction de chronomètre dans React que j'aimerais arrêter après 15 minutes. Je ne sais pas comment utiliser clearInterval() dans ce cas :

  const [timer, setTimer] = useState(0);
  const [isActive, setIsActive] = useState(false);
  const [isPaused, setIsPaused] = useState(false);
  const countRef = useRef(null);
  const lastUpdatedRef = useRef(null);
  const [minutes,setMinutes] = useState(0)
  const [seconds,setSeconds] = useState(0)

  const timeCeiling = 900; //maximum minutes is 15
  const timeFloor = 60; //maximum seconds is 60 so it resets after

  useEffect(() => {
    if (timer < timeCeiling) {
      setMinutes(Math.floor(timer / 60));
      setSeconds(timer % 60);
    } else {
      setMinutes(15);
      setSeconds(0);
    }
  }, [timer]);

  const handleStart = () => {
    setIsActive(true);
    setIsPaused(true);
    countRef.current = setInterval(() => {
      setTimer((timer) => timer + 1);
    }, 1000);
    lastUpdatedRef.current = setInterval(() => {
      setLastUpdated(Date.now());
    }, 30000);
  };

L'utilisateur clique sur le bouton handleStart qui déclenche un useEffect . Il dispose également d'un lastUpdated qui déclenche une autre fonction toutes les 30 secondes.

L'horloge devrait s'arrêter après 15:00 mais elle continue après - où dois-je mettre clearInterval de manière à ce que l'horloge s'arrête au bout de 15 minutes ? Ou existe-t-il un autre moyen de procéder ?

1voto

Drew Reese Points 1957

Je le placerais dans le useEffect qui s'exécute à chaque fois que timer mises à jour. Effacer l'intervalle dans la branche else lorsque la limite est atteinte.

useEffect(() => {
  if (timer < timeCeiling) {
    setMinutes(Math.floor(timer / 60));
    setSeconds(timer % 60);
  } else {
    clearInterval(countRef.current);
    setMinutes(15);
    setSeconds(0);
  }
}, [timer]);

Vous pouvez également ajouter un useEffect pour effacer les minuteries en cours si le composant est démonté avant que vous ne les effaciez manuellement.

useEffect(() => {
  return () => {
    clearInterval(countRef.current);
    clearInterval(lastUpdatedRef.current);
  };
}, []);

1voto

Max Programming Points 43

Je pense que vous devriez utiliser clearInterval dans le bloc else dans useEffect . Peut-être de cette manière :

else {
  setMinutes(15);
  setSeconds(0);
  clearInterval(countRef.current) // I hope this works
}

1voto

Viet Points 3460

Vous pouvez ajouter un intervalle clair dans la condition "else" :

useEffect(() => {
  if (timer < timeCeiling) {
    setMinutes(Math.floor(timer / 60));
    setSeconds(timer % 60);
  } else {
    setMinutes(15);
    setSeconds(0);
    countRef.current && clearInterval(countRef.current);
    lastUpdatedRef.current && clearInterval(lastUpdatedRef.current);
  }
}, [timer]);

Et vous devez effacer l'intervalle lorsque le composant est démonté :

useEffect(() => {
  return () => {
    countRef.current && clearInterval(countRef.current);
  };
}, [countRef]);

useEffect(() => {
  return () => {
    lastUpdatedRef.current && clearInterval(lastUpdatedRef.current);
  };
}, [lastUpdatedRef]);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X