Выбор ответа Junior Ref и DOM обновлено

Где хранить id таймера

Вопрос

Кнопка «Стоп» не останавливает таймер, если между нажатиями компонент перерендерился. Почему?

function Timer() {
  const [ticks, setTicks] = useState(0);
  let timerId;
  const start = () => {
    timerId = setInterval(() => setTicks(t => t + 1), 1000);
  };
  const stop = () => clearInterval(timerId);
  // ...
}

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: let timerId живёт один рендер, в новом он undefined. Переменная в теле компонента живёт один рендер.

Варианты ответа

  1. let timerId живёт один рендер, в новом он undefinedправильный ответ
  2. clearInterval нельзя вызывать в обработчике, только в очистке
  3. Нужно хранить id в state, иначе React его не отслеживает
  4. Таймеры в React работают лишь внутри useEffect

Разбор

Переменная в теле компонента живёт один рендер. После setTicks компонент перерендерился, и stop из нового рендера видит свежую timerId = undefined. Нужен useRef: он сохраняется между рендерами и не вызывает лишний рендер, в отличие от state. clearInterval в обработчике вызывать можно, и таймеры не обязаны жить в эффектах.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме