Set Countdown Timer React JS
Solution 1:
using setInterval
will make me a headache figuring out what happened every time after a react rerender process with more and more interval being added to the event loop, I would recommend using setTimeout
with componentDidUpdate method to udpate state and clean up at the end or using hooks which made life easier
here is a solution with hooks
function App() {
const [seconds, setSeconds] = useState(0)
const [minutes, setMinutes] = useState(5)
function updateTime() {
if (minutes == 0 && seconds == 0) {
//reset
setSeconds(0);
setMinutes(5);
}
else {
if (seconds == 0) {
setMinutes(minutes => minutes - 1);
setSeconds(59);
} else {
setSeconds(seconds => seconds - 1);
}
}
}
useEffect(() => {
// use set timeout and be confident because updateTime will cause rerender
// rerender mean re call this effect => then it will be similar to how setinterval works
// but with easy to understand logic
const token = setTimeout(updateTime, 1000)
return function cleanUp() {
clearTimeout(token);
}
})
return (<p>
time: {minutes}:{seconds}
</p>);
}
Solution 2:
I suggest creating and tracking a single time state, i.e. seconds, that is incremented every second, and simply compute the minutes and seconds to display.
Minutes
String(Math.floor(time / 60)).padStart(2, '0'); // 00, 01, 02, ...59
Seconds
String(time % 60).padStart(2, '0'); // 00, 01, 02, ...59
The countdown time can be computed from subtracting the seconds remainder for each interval from each interval, i.e. 300 - time % 300
RESET_INTERVAL_S - time % RESET_INTERVAL_S
Given a component to display overall timer and countdown timer, and a utility function to render formatted time
const formatTime = (time) =>
`${String(Math.floor(time / 60)).padStart(2, "0")}:${String(
time % 60
).padStart(2, "0")}`;
const Timer = ({ time }) => {
const timeRemain = RESET_INTERVAL_S - (time % RESET_INTERVAL_S);
return (
<>
<div>Time: {formatTime(time)}</div>
<div>Countdown Timer: {formatTime(timeRemain)}</div>
</>
);
};
Class-based implementation
class IntervalTimerClass extends Component {
state = {
time: 0
};
timerId = null;
componentDidMount() {
this.timerId = setInterval(() => {
this.setState((prevState) => ({ time: prevState.time + 1 }));
}, 1000);
}
componentWillUnmount() {
clearInterval(this.timerId);
}
render() {
return <Timer time={this.state.time} />;
}
}
Functional component implementation
const IntervalTimerFunctional = () => {
const [time, setTime] = useState(0);
useEffect(() => {
const timerId = setInterval(() => {
setTime((t) => t + 1);
}, 1000);
return () => clearInterval(timerId);
}, []);
return <Timer time={time} />;
};
Solution 3:
import {useState} from 'react'
set consts
function Timer(){
const[timer, setTimer] = useState(121)
const sec = timer%60 //set seconds
const min = timer/60 //set minutes
const clock = `${min}:${sec > 9: sec: '0'+sec}` //create 'clock'
const startTimer = //now start the 'timer'
timer > -1?
setTimeout(()=>{
setTimer(timer-1), setTimer(clock)
},1000):'done'
if(timer === 0 && min === 0 && sec === 0){
console.log('you done')
}
if(timer && min === 0 && sec === 0 ){
min -=1
sec += 59
}
return(
<div>{timer}</div>
)
}
Post a Comment for "Set Countdown Timer React JS"