Задать вопрос
@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" />}
            >
)
  • Вопрос задан
  • 172 просмотра
Подписаться 1 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    React-разработчик
    3 месяца
    Далее
  • Merion Academy
    Frontend-разработка на React
    4 месяца
    Далее
  • ProductStar
    React: отточите навыки интерфейсной разработки
    6 недель
    Далее
Пригласить эксперта
Ответы на вопрос 2
Не будет работать setInterval со стейтом так как вы написали, не уверен зачем вам вообще текущий интервал в стейте, если все в рамках одной функции происходит,
countdown с потолка взято
Если меняется какая то из переменных в стейте, вам нужно использовать useEffect и пересоздавать таймер с новыми переменными.
Если нужно использовать стейт, я бы предпочел setTimeout
Ответ написан
@bitwheeze
Я не специалист, возможно вру. У вас "export const App" это функция, которая запускается каждый раз, когда надо перерисовать компоненту. В один из таких вызовов вы создаете таймер и передаете ему стрелочную функцию, которая будет вызываться с заданной периодичностью. После того как App функция создаст таймер с этой вашей функцией, она закончит свою работу и все состояние стэка вместе с переменными уйдет в нирвану. Потом когда таймер вызовет вашу стрелочную функцию, то ей просто уже негде будет брать данные. В лучшем случае она будет все еще иметь доступ к тем значениям, которые были в момент создания таймера.

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

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

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

Похожие вопросы
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
IT ATLAS Москва
от 200 000 до 250 000 ₽
ITK academy Казань
от 50 000 до 90 000 ₽