@Banjamin
Пишу

Как правильно реализовать таймер на React?

Добрый день. При реализации компонента таймера столкнулся с проблемой, по истечению нескольких минут минуты начинаю уменьшаться раньше на пару секунд. То есть за две-три секунды минуты уже уменьшаются на единицу. Подскажите какие ошибки я допустил в компоненте и как решить проблему.
Заранее спасибо.

const TimerVidjet = ({ body }) => {
    const [type, setType] = useState(body.type)
    const { days, hours, minutes, seconds } = createTime(type, body)
    const [second, setSecond] = useState(seconds)
    const [minut, setMinut] = useState(minutes)
    const [hour, setHour] = useState(hours)
    const [day, setDay] = useState(days)

    useEffect(() => {
        if (day === 0 && hour === 0 && minute === 0 && second === 0) return
       
        const timer = setInterval(() => {    
            if (second === 0) {
                console.log('0 секунд')
                setMinut(state => state -= 1)
                setSecond(59)
            }
            if (minut === 0) {
                setHour(state => state -= 1)
                setMinut(59)
            }
            if (hour === 0) {
                setDay(state => state -= 1)
                setHour(23)
            }
            setSecond(state => state = state - 1)
        }, 1000)

        return () => clearInterval(timer)
    }, [second])

    return (
        <div className='questions-container'>
            <div className='container question-center'>
                <div className='questions-header'>
                    <div className='questions-buttons'>
                        <div className='icon-conteiner'>
                            <FontAwesomeIcon /* onClick = {()=>replaceVidj('up', id)} */ icon={faAngleUp} />
                        </div>
                        <div className='icon-conteiner'>
                            <FontAwesomeIcon /* onClick = {()=>replaceVidj('down', id)} */ icon={faAngleDown} />
                        </div>
                        <div className='icon-conteiner'>
                            <FontAwesomeIcon /* onClick={editHandler} */ icon={faEdit} />
                        </div>
                        <div className='icon-conteiner' /* onClick={delHandler} */ color='green'>
                            <FontAwesomeIcon color={'red'} icon={faTrashAlt} />
                        </div>
                    </div>
                </div>
                <div className='questions-body'>
                    <h3 className='question-h3'>До конца акции </h3>
                    <div className='timer-number-conteiner'>
                        <ul className='timer-number-list pl-0'>
                            <li className='timer-number-item d-flex justify-content-center flex-column'>
                                <div className='timer-number my-0 mx-auto'>
                                    <TimerNumber title='Дни' number={days} />
                                </div>
                            </li>
                            <li className='timer-number-item d-flex justify-content-center flex-column'>
                                <div className='timer-number my-0 mx-auto'>
                                    <TimerNumber title='Часы' number={hours} />
                                </div>
                            </li>
                            <li className='timer-number-item d-flex justify-content-center flex-column'>
                                <div className='timer-number my-0 mx-auto'>
                                    <TimerNumber title='Минуты' number={minute} />
                                </div>
                            </li>
                            <li className='timer-number-item d-flex justify-content-center flex-column'>
                                <div className='timer-number my-0 mx-auto'>
                                    <TimerNumber title='Секунды' number={second} />
                                </div>
                            </li>

                        </ul>
                    </div>
                </div>
            </div>
        </div>
    )
}
export default TimerVidjet
  • Вопрос задан
  • 1043 просмотра
Пригласить эксперта
Ответы на вопрос 1
Почитайте как лучше использовать setInterval - и как бонус - useInterval
Можно воспользоваться либой

А ошибка - при каждом изменении second у вас происходит clearInterval, и сразу в useEffect идет подписка - это накладные расходы. В статье выше описаны проблемы
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы