S
S
Sergey2021-02-04 11:04:02
React
Sergey, 2021-02-04 11:04:02

How to properly implement a timer in React?

Good afternoon. When implementing the timer component, I ran into a problem, after a few minutes of a minute, I start to decrease earlier by a couple of seconds. That is, in two or three seconds, the minutes are already decreasing by one. Tell me what mistakes I made in the component and how to solve the problem.
Thanks in advance.

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

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Andrey Pastukhov, 2021-02-04
@tyllo

Read how to use setInterval better - and as a bonus - useInterval
You can use either
A error - every time you change second , you have a clearInterval, and immediately a subscription goes to useEffect - this is overhead. The article above describes the problems

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question