Храните накопленное время и момент старта, а интервал используйте только для обновления отображения. Так секундомер не накапливает ошибку от задержек тиков и может продолжаться после Stop.
React‑компонент секундомера с управлением
Храните накопленное время и момент старта, а интервал используйте только для обновления отображения. Так секундомер не накапливает ошибку от задержек тиков и может продолжаться после Stop.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Разработать React‑компонент, который функционирует как секундомер. Необходимо добавить две кнопки — «Start» и «Stop», отображать текущий прошедший интервал времени и обеспечить возможность остановки таймера по нажатию кнопки «Stop».
Ответ
Храните накопленное время и момент старта, а интервал используйте только для обновления отображения. Так секундомер не накапливает ошибку от задержек тиков и может продолжаться после Stop.
function Stopwatch() {
const [running, setRunning] = React.useState(false);
const [elapsed, setElapsed] = React.useState(0);
const saved = React.useRef(0), started = React.useRef(null);
React.useEffect(() => {
if (!running) return;
const timer = setInterval(() => {
if (started.current !== null) setElapsed(saved.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;
saved.current += performance.now() - started.current;
started.current = null; setElapsed(saved.current); setRunning(false);
};
return <><output>{(elapsed / 1000).toFixed(1)} с</output>
<button onClick={start} disabled={running}>Start</button>
<button onClick={stop} disabled={!running}>Stop</button></>;
}
Нужен импорт React. Повторные Start не создают новые интервалы; cleanup очищает таймер при остановке и размонтировании. Время сравнивается по монотонным часам performance.now.