таймер отключения в react не работает должным образом

#reactjs #timer #counter #lifecycle

#reactjs #таймер #счетчик #жизненный цикл

Вопрос:

Я новичок. У меня вопрос, я создал таймер счетчика в React, но, к сожалению, он не работает должным образом. Я не могу найти ошибку, кто-нибудь может мне помочь?

 import React, { useState, useEffect } from "react";

export default function CountDown() {
 let [seconds, setSeconds] = useState(3);
 let [minutes, setMinutes] = useState(59);
 let [hours, setHours] = useState(3);

 useEffect(() => {
   const interval = setInterval(() => {
     setCounddownTimer();
     console.log("i am working", { seconds, minutes, hours });
     return () => clearInterval(interval);
   }, 1000);
 }, []);
 const setCounddownTimer = () => {
   if (hours === 0 amp;amp; minutes === 0 amp;amp; seconds === 0) {
     timerReset();
   } else if (minutes === 0 amp;amp; seconds === 0) {
     console.log({ seconds, minutes, hours });
     setHours(--hours);
     setMinutes(59);
     setSeconds(59);
   } else if (seconds === 0) {
     setSeconds(59);
     setMinutes(--minutes);
   } else {
     setSeconds(--seconds);
   }
 };
 const timerReset = () => {
   setSeconds(59);
   setMinutes(59);
   setHours(3);
 };
 const addLeadingZero = (number) => {
   return number < 10 ? "0"   number : number;
 };
 const style = {
   "text-align": "center",
   "font-weight": "bold",
   color: "#cf0000"
 };
 return (
   <div style={style}>
     {addLeadingZero(hours)}:{addLeadingZero(minutes)}:
     {addLeadingZero(seconds)}
   </div>
 );
}

 

Я также вставляю ссылку на codesandbox https://codesandbox.io/s/epic-hopper-f9dy4?file=/src/App.js:0-1277

Комментарии:

1. можете ли вы указать свои ожидания и с чем конкретно у вас возникли проблемы?

2. хорошо, секунды уменьшаются на 1 до значения 0, следующие минуты меняются на 58. Далее происходит волшебство. Секунды равны 59, а минуты все еще уменьшаются.

Ответ №1:

Ваше useEffect return утверждение было внутри setInterval() . Он должен быть снаружи.

 const interval = setInterval(() => {
  setCounddownTimer();
  console.log("i am working", { seconds, minutes, hours });
}, 1000);

return () => clearInterval(interval);
 

Обновить

Кроме того, вы должны были вставить hours, minutes, seconds useEffect массив зависимостей, поскольку рендеринг зависит от этих 3 состояний. В противном случае секунды будут отсчитываться, пока таймер не достигнет 03:58:59, но затем начнется обратный отсчет минут.

Комментарии:

1. Большое вам спасибо, конечно, он должен быть снаружи. Я пропустил это.

2. К вашему сведению, массив зависимостей является вторым пользователем в useEffect, где в настоящее время у вас пустой массив.