Не работает timer react.js

Рейтинг: 0Ответов: 1Опубликовано: 16.08.2023

При нажатии на Start запускается функция startTimer, она проверяет запущен ли таймер, если не запущен то начинается таймер прибавляя +1 секунду в secondsData, после 59 секунд должна добавиться +1 минута в minutesData, но вместо этого у меня добавляется +2.

function App() {
    const [start, setStart] = React.useState(0);
    const [secondsData, setSecondsData] = React.useState(0);
    const [minutesData, setMinutesData] = React.useState(0);
    const [hoursData, setHoursData] = React.useState(0);
    const [secondsInterval, setSecondsInterval] = React.useState(null);

    function startTimer() {
        if (start === 0) {
            console.log('Started!!!');
            setStart(1);
            setSecondsInterval(
                setInterval(function () {
                    setSecondsData((prevSecondsData) => {
                        if (prevSecondsData >= 59) {
                            setSecondsData(0);
                            setMinutesData((prevMinutesData) => {
                                if (prevMinutesData >= 59) {
                                    setMinutesData(0);
                                    setHoursData((prevHoursData) => prevHoursData + 1);
                                }
                                return (prevMinutesData + 1) % 60; // Обновляем минуты, учитывая переход через 60
                            });
                        } else {
                            return prevSecondsData + 1;
                        }
                    });
                }, 1000),
            );
        } else {
            alert('Timer is already started!');
        }
    };

    function stopTimer() {
        if (start == 1) {
            setSecondsInterval(null);
            clearInterval(secondsInterval);
            setStart(0);
        } else {
            alert('Timer is already stopped!');
        }
    }

    function endTimer() {
        if (start == 1) {
            setSecondsInterval(null);
            clearInterval(secondsInterval);
            setSecondsData(0);
            setMinutesData(0);
            setHoursData(0);
            setStart(0);
        } else {
            alert('Timer is already ended!');
        }
    }

    return (
        <>
            <div className='timer'>
                <div className='timer__block'>
                    <div className='timer__spans'>
                        <span>{hoursData < 10 ? '0' + hoursData : hoursData}</span>
                        <span>:</span>
                        <span>{minutesData < 10 ? '0' + minutesData : minutesData}</span>
                        <span>:</span>
                        <span>{secondsData < 10 ? '0' + secondsData : secondsData}</span>
                    </div>
                    <div className='timer__btns'>
                        <button onClick={startTimer}>Start</button>
                        <button onClick={stopTimer}>Stop</button>
                        <button onClick={endTimer}>End</button>
                    </div>
                </div>
            </div>
        </>
    );
}

Ответы

▲ 0

Вот пример того таймера про него я писал в комментариях... Все работает исключительно "от стейта", потому как это основная идея Реакт.

//
function Timer({type}) {
  const [tm, setTm] = React.useState(0)
  React.useEffect(_ => {
    if (type === 'stp') return
    if (type === 0) {
      setTm(0)
      return
    }
    const t = setTimeout(_ => setTm(tm + 1), 1000)
    return _ => clearTimeout(t)
  }, [type, tm])
  const t1 = Math.trunc(tm / 3600).toString().padStart(2, 0)
  const t2 = Math.trunc((tm % 3600) / 60).toString().padStart(2, 0)
  const t3 = (tm % 60).toString().padStart(2, 0)
  return <div>
    {t1}:{t2}:{t3}
  </div>
}
//
function Control({act}) {
  return <div>
    <button onClick={_ => act('act')}>Старт</button>
    <button onClick={_ => act('stp')}>Стоп</button>
    <button onClick={_ => act(0)}>Отмена</button>
  </div>
}
//
function App() {
  const [type, setType] = React.useState(0)
  return <div>
    <Timer type={type} />
    <Control act={setType} />
  </div>
}
const domContainer = document.querySelector('#like_button_container');
const root = ReactDOM.createRoot(domContainer);
root.render(<App />);
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<div id="like_button_container"></div>