I am getting the negative counter which is a bit problem for me and I am also a newbie so please help,other than the result I would also like to get the tips and tricks to avoid such mistakes,I also getting the negative time not only for days but also for hours seconds and minutes too
My code is -:
import React,{ useState,useEffect } from 'react'
const Clock = () => {
const [days, setDays] = useState();
const [hours, setHours] = useState();
const [minutes, setMinutes] = useState();
const [seconds, setSeconds] = useState();
let interval;
const countDown = () => {
const destination = new Date('Oct 22, 2022').getTime();
interval = setInterval(() => {
const now = new Date().getTime();
const different = destination - now ;
const seconds = Math.floor((different / 1000) % 60);
const minutes = Math.floor((different / 1000 / 60) % 60);
const hours = Math.floor((different / (1000 * 60 * 60)) % 24);
const days = Math.floor(different / (1000 * 60 * 60 * 24));
if(destination < 0) clearInterval(interval.current);
else{
setDays(days)
setHours(hours)
setMinutes(minutes)
setSeconds(seconds)
}
})
}
useEffect(() => {
countDown();
})
return (
<div className="clock__wrapper d-flex align-items-center gap-3">
<div className="clock__data d-flex align-items-center gap-3">
<div className='text-center'>
<h1 className='text-white fs-3 mb-2'>{days}</h1>
<h5 className='text-white fs-6'>Days</h5>
</div>
<span className='text-white fs-3'>:</span>
</div>
<div className="clock__data d-flex align-items-center gap-3">
<div className='text-center'>
<h1 className='text-white fs-3 mb-2'>{hours}</h1>
<h5 className='text-white fs-6'>Hours</h5>
</div>
<span className='text-white fs-3'>:</span>
</div>
<div className="clock__data d-flex align-items-center gap-3">
<div className='text-center'>
<h1 className='text-white fs-3 mb-2'>{minutes}</h1>
<h5 className='text-white fs-6'>Minute</h5>
</div>
<span className='text-white fs-3'>:</span>
</div>
<div className="clock__data d-flex align-items-center gap-3">
<div className='text-center'>
<h1 className='text-white fs-3 mb-2'>{seconds}</h1>
<h5 className='text-white fs-6'>Seconds</h5>
</div>
</div>
</div>
)
}
export default Clock
CodePudding user response:
setTimeout is enough because once you need to update the diff
the updated diff
(put in useEffect dependency array) will automatically execute the function again which will trigger setTimeout again
and I made calculateDiffFromNow alone, it can be used in another component, and it will make your component a little cleaner
import React, { useEffect, useState } from 'react';
function calculateDiffFromNow(date: Date) {
const now = new Date().getTime();
const different = date.getTime() - now;
const seconds = Math.floor((different / 1000) % 60);
const minutes = Math.floor((different / 1000 / 60) % 60);
const hours = Math.floor((different / (1000 * 60 * 60)) % 24);
const days = Math.floor(different / (1000 * 60 * 60 * 24));
return {
days,
hours,
seconds,
minutes
}
}
const Clock = ({ destination }: { destination: Date }) => {
// only store the new differece between now and your destination
const [diff, setDiff] = useState(calculateDiffFromNow(destination));
useEffect(() => {
setTimeout(function calculateTheNewDiff(){
let newDiff = calculateDiffFromNow(destination)
let canBeUpdated = newDiff.seconds >= 0 && newDiff.minutes >= 0 && newDiff.hours >= 0 && newDiff.days >= 0;
if (canBeUpdated)
setDiff(newDiff);
}, 1000);
}, [diff]);
return (
<div className="clock__wrapper d-flex align-items-center gap-3">
<div className="clock__data d-flex align-items-center gap-3">
<div className='text-center'>
<h1 className='text-white fs-3 mb-2'>{diff.days}</h1>
<h5 className='text-white fs-6'>Days</h5>
</div>
<span className='text-white fs-3'>:</span>
</div>
<div className="clock__data d-flex align-items-center gap-3">
<div className='text-center'>
<h1 className='text-white fs-3 mb-2'>{diff.hours}</h1>
<h5 className='text-white fs-6'>Hours</h5>
</div>
<span className='text-white fs-3'>:</span>
</div>
<div className="clock__data d-flex align-items-center gap-3">
<div className='text-center'>
<h1 className='text-white fs-3 mb-2'>{diff.minutes}</h1>
<h5 className='text-white fs-6'>Minute</h5>
</div>
<span className='text-white fs-3'>:</span>
</div>
<div className="clock__data d-flex align-items-center gap-3">
<div className='text-center'>
<h1 className='text-white fs-3 mb-2'>{diff.seconds}</h1>
<h5 className='text-white fs-6'>Seconds</h5>
</div>
</div>
</div>
)
}
function App() {
return (
<div className="App">
<Clock destination={new Date('2022-10-22T09:50:01.400Z')} />
</div>
);
}
export default App;
```jsx
Hope you find it useful