Answer the question
In order to leave comments, you need to log in
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
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 questionAsk a Question
731 491 924 answers to any question