I have this countdown timer logics, I am using useEffect to set the initial state depending on the incoming props from a parent component, then when the user clicks on an icon the set Time function gets triggered starting the countdown any idea how to set the conditional for it to stop ? the function ran once and I cannot set the conditional form the setInterval it self ?
//incoming Rest props 30 60 90 sec / 1,2,3,4,5 min
// When the comopnent gets renderd
useEffect(() => {
const check = rest.includes('Sec');
if (check) {
let secs = parseFloat(rest.slice(0, 2));
setTimer({ ...timer, minutes: secs === 90 ? 1 : 0, seconds: secs === 90 ? 30 : secs });
}
}
// State
const [timer, setTimer] = useState<{ minutes: number; seconds: number }>({ minutes: 0, seconds: 0 });
// On click
const setTime = () => {
setInterval(() => setTimer((prevState) => ({...prevState,
minutes: prevState.minutes, seconds: prevState.seconds - 1 })), 1000);
};
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
At the first, Use useEffect
only once and store
interval state.
You can stop it by clearInterval
and return null
in your setState
const [timer, setTimer] = useState(YOUR_DATETIME_VALUE);
const [loop, setLoop] = useState(null);
useEffect(() => {
setTimeout(() => {
setTimer(new Date(timer.getTime() - timer.getMilliseconds()));
setLoop(setInterval( () => {
setTimer(new Date(timer.getTime() - 1000));
}, 1000));
}, timer.getMilliseconds());
}, []);
const stopHandler = () => {
setLoop(interval => {
clearInterval(interval);
return null;
});
}
Notice: use stopHandler
if you want to stop it
if (Math.abs(new Date().getTime() - timer.getTime) < 1000) {
stopHandler();
}
Notice: The millisecond difference is calculated in setTimeout