Kentavr16
@Kentavr16
long cold winter

Как использовать setInterval для простейшего таймера?

доброго времени суток. Начинаю изучение js, и сразу же подводный камень - не могу корректно использовать setInterval. К примеру при нажатии на кнопку хочу запустить простейший таймер, считающий секунды:
function App() {
  const[sec,setSec] =useState(0);
  const MyTimer =()=>setInterval(()=>{setSec(sec+1)},1000);
  return (
    <div>
      <button onClick={MyTimer}>start</button>
      <h1>{sec}</h1>

    </div>
  );
}

export default App;


при нажатии на кнопку интервал срабатывает 1 раз. при повторном нажатии цифры вообще скачут. Получилось сделать такой же таймер с использованием setTimeout, но хочу понять принцип работы. Рылся на всех ветках - простого и корректного объяснения не нашел. Помогите с кодом пожалуйста.
  • Вопрос задан
  • 909 просмотров
Решения вопроса 1
@tehfreak
Все дело в замыкании. Переданная в setInterval функция замыкает в себе переменную seconds в значении ноль. Интервал работает, но при каждом следующем вызове функции переменная seconds имеет прежнее значение.

В setSeconds нужно передать функцию, которая будет вызвана с актуальным значением seconds.

Вот так:
function App() {
    
    const [ seconds, setSeconds ] = React.useState(0)

    // старый вариант, не работает
    const startTimer = () => {
        setInterval(() => {
            setSeconds(seconds + 1)
        }, 1000)
    }

    // новый вариант, работает
    const startTimer = () => {
        setInterval(() => {
            setSeconds((seconds) => {
                return seconds + 1
            })
        }, 1000)
    }

    return (
        <div>
            <button onClick={startTimer}>start</button>
            <h1>{seconds}</h1>
        </div>
    )
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы