@Marat20
Frontend разработчик

Почему не передается обновленный state в интервал?

Таймер Помодоро. При каждом обновлении стейт таймера в интервале, почему-то, передается начальное значение таймера, когда я только запускал таймер. И получается, что проверки на (timer === 0 ....) не проходят, потому что в интервале таймер (значение) всегда одинаковое (хотя оно обновляется). Почему так происходит и как сделать, чтобы после каждой пройденной секунды в интервале было обновленное значение таймера??? (Код не весь, а только часть, где видна проблема)

export const App = () => {
  const [breakLength, setBreakLength] = useState(5);
  const [sessionLength, setSessionLength] = useState(25);
  const [mode, setMode] = useState('Session');
  const [timer, setTimer] = useState(3);
  const [timerRunning, setTimerRunning] = useState(false);

const countDownTimer = () => {
    clearInterval(countdown);
    
    countdown = setInterval(() => {
      if (timer === 0 && mode === 'Session') {
        setMode('Break');
        setTimer(breakLength * 60 + 1);
      }
    
      if (timer === 0 && mode === 'Break') {
        setMode('Session');
        setTimer(sessionLength * 60 + 1);
      }
      setTimer(prevState => prevState - 1);

    }, 1000);

    setTimerRunning(true);

  };


return (
<Button
              id="start_stop"
              onClick={() => {
                countDownTimer();
              }}
              icon={<FaPlay className="fa fa-play" />}
            >
)
  • Вопрос задан
  • 130 просмотров
Пригласить эксперта
Ответы на вопрос 2
Не будет работать setInterval со стейтом так как вы написали, не уверен зачем вам вообще текущий интервал в стейте, если все в рамках одной функции происходит,
countdown с потолка взято
Если меняется какая то из переменных в стейте, вам нужно использовать useEffect и пересоздавать таймер с новыми переменными.
Если нужно использовать стейт, я бы предпочел setTimeout
Ответ написан
@bitwheeze
Я не специалист, возможно вру. У вас "export const App" это функция, которая запускается каждый раз, когда надо перерисовать компоненту. В один из таких вызовов вы создаете таймер и передаете ему стрелочную функцию, которая будет вызываться с заданной периодичностью. После того как App функция создаст таймер с этой вашей функцией, она закончит свою работу и все состояние стэка вместе с переменными уйдет в нирвану. Потом когда таймер вызовет вашу стрелочную функцию, то ей просто уже негде будет брать данные. В лучшем случае она будет все еще иметь доступ к тем значениям, которые были в момент создания таймера.

Стейт поменяется уже в в другом вызове функции App, та стрелочная функция таймера о ней ничего не знает.

Я не понял, что вы хотите там изобразить. Возможно вам надо поискать useDebounce хук.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы