Реагировать useRef: текущее значение не определено

Я следую учебнику для начинающих по хукам useState и useRef, пытаясь реализовать простой таймер в реакции.

Я использую переменную interval для хранения значения из setInterval()

При нажатии кнопки запуска я могу правильно console.info значение интервала. Однако при нажатии кнопки «Стоп» interval.current регистрируется в консоли как undefined. Следовательно, stopTimer() не работает должным образом.

Почему interval.current печатает undefined, когда он явно установлен в startTimer (и зарегистрирован там)? Что мне здесь не хватает?

import React, { useState, useRef } from 'react';

const pad = (time) => {
  return time.toString().padStart(2, "0");
};


function App() {
  const [title, setTitle] = useState("Pomodoro!");
  const [timeLeft, setTimeLeft] = useState(5);
  const interval = useRef(null);

  const startTimer = () => {
    interval.current = setInterval(() => {
      setTimeLeft((timeLeft) => {
        if (timeLeft >= 1) {
          return timeLeft - 1;
        }
        return 0;
      });
    }, 1000);
    console.info(interval.current, " :in start");
  }

  const stopTimer = (interval) => {
    console.info("in stop: ", interval.current);
    clearInterval(interval.current);
  }

  const resetTimer = () => { }

  const minutes = pad(Math.floor(timeLeft / 60));
  const seconds = pad((timeLeft - minutes * 60));


  return (

    <div>
      <div>{title}</div>
      <div>
        <span>{minutes}</span>
        <span>:</span>
        <span>{seconds}</span>
      </div>
      <div>
        <button onClick = {startTimer}>Start</button>
        <button onClick = {stopTimer}>Stop</button>
        <button onClick = {resetTimer}>Reset</button>
      </div>
    </div>
  );
}

export default App;

вывод в консоль

6 ": в начале" в остановке: не определено

Спасибо

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
2 849
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Учитывая, что делает ваш код, я считаю, что interval должна быть переменной состояния, а не ссылкой. То есть вы должны использовать

const [interval, setInterval] = useState(null);

вместо const interval = useRef(null);

Ссылки используются для привязки к элементам DOM (например, к элементу формы, на который вы хотите ссылаться при нажатии кнопки). Только когда переменная ref правильно ссылается на элемент DOM, определяется их атрибут current.

Хотя ref часто используется для привязки элементов DOM, он этим не ограничивается.

buzatto 25.12.2020 01:10
Ответ принят как подходящий

Я полагаю, это потому, что вы передаете переменную более низкой области видимости, называемую interval, в stopTimer, но когда вы вызываете stopTimer, вы не передаете аргумент, поэтому он не определен при доступе к нему.

Вероятно, вы имеете в виду interval, который вы определили как ref, поэтому вам нужно просто получить к нему доступ, не передавая interval в stopTimer, попробуйте следующее:

  const stopTimer = () => {
    console.info("in stop: ", interval.current);
    clearInterval(interval.current);
  }

Другие вопросы по теме