Создание простого таймера в React с кнопками запуска и остановки

Храните счётчик и флаг running. Эффект создаёт один интервал при запуске и очищает его при остановке или размонтировании; повторный Start не должен умножать таймеры.

Короткий ответ

Что ответить на собеседовании

Храните счётчик и флаг running. Эффект создаёт один интервал при запуске и очищает его при остановке или размонтировании; повторный Start не должен умножать таймеры.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо реализовать компонент таймера, который отображает текущий счётчик и имеет две кнопки — «Start» и «Stop». При нажатии на «Start» счётчик начинает увеличиваться, а «Stop» останавливает его.

function Stopwatch() {
    return (
        <div>
            <button>Start</button>
            <button>Stop</button>
            <div>0</div>
        </div>
    );
}

export default function App() {
    return <Stopwatch />;
}

Ответ

Храните счётчик и флаг running. Эффект создаёт один интервал при запуске и очищает его при остановке или размонтировании; повторный Start не должен умножать таймеры.

import { useEffect, useState } from 'react';
function Stopwatch() {
  const [count, setCount] = useState(0);
  const [running, setRunning] = useState(false);
  useEffect(() => {
    if (!running) return;
    const timer = setInterval(() => setCount(value => value + 1), 1000);
    return () => clearInterval(timer);
  }, [running]);
  return <div>
    <button onClick={() => setRunning(true)} disabled={running}>Start</button>
    <button onClick={() => setRunning(false)} disabled={!running}>Stop</button>
    <div>{count}</div>
  </div>;
}

Это счётчик срабатываний таймера: в фоновой вкладке он может отставать от реального времени. Для точного секундомера рассчитывайте прошедшее время по временным отметкам, а интервал используйте только для обновления экрана.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее