Для секундомера считайте разницу performance.now(), а не количество тиков. При Stop сохраняйте накопленное время, при новом Start продолжайте с него.
React‑таймер со стартом и остановкой
Для секундомера считайте разницу performance.now(), а не количество тиков. При Stop сохраняйте накопленное время, при новом Start продолжайте с него.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Разработайте React‑компонент, который функционирует как секундомер. В интерфейсе должны быть две кнопки — «Start» и «Stop». При нажатии «Start» таймер начинает отсчёт, отображая прошедшее время, а при нажатии «Stop» – останавливается и сохраняет текущий результат. Компонент должен корректно обновлять отображаемое время в реальном времени.
Ответ
Для секундомера считайте разницу performance.now(), а не количество тиков. При Stop сохраняйте накопленное время, при новом Start продолжайте с него.
import { useEffect, useRef, useState } from 'react';
function Stopwatch() {
const [elapsed, setElapsed] = useState(0);
const [running, setRunning] = useState(false);
const started = useRef(null);
const accumulated = useRef(0);
useEffect(() => {
if (!running) return;
const timer = setInterval(() => {
if (started.current !== null) setElapsed(accumulated.current + performance.now() - started.current);
}, 100);
return () => clearInterval(timer);
}, [running]);
const start = () => {
if (started.current !== null) return;
started.current = performance.now(); setRunning(true);
};
const stop = () => {
if (started.current === null) return;
accumulated.current += performance.now() - started.current;
started.current = null;
setElapsed(accumulated.current); setRunning(false);
};
return <div>
<button onClick={start} disabled={running}>Start</button>
<button onClick={stop} disabled={!running}>Stop</button>
<output>{(elapsed / 1000).toFixed(1)} с</output>
</div>;
}
Интервал лишь обновляет отображение, поэтому задержанный тик не теряет прошедшее время. После размонтирования интервал очищается; сохранение между перезагрузками этим примером не предусмотрено.