@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 хук.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
19 мар. 2024, в 11:54
3000 руб./за проект
19 мар. 2024, в 11:52
3000 руб./за проект
19 мар. 2024, в 11:49
10000 руб./за проект