CountDown Timer using React Hooks
Photo by Lukas Blazek on Unsplash
- Use the useState() hook to create a state variable to hold the time value, initialize it from the props and destructure it into its components.
- Use the useState() hook to create the started and count state variables, used to prevent the timer from ticking on initial mount and get the number of restarts.
- Create a method timer, that updates the time values based on the current value (i.e. decreasing the time by one second).
- Create a method start, will trigger the timer.
- Create a method restart, that restart timer again when its over. In this method you can also set random timing from props.
- Create a method reset, that resets all state variables to their initial states.
- Use the the useEffect() hook to call the timer method every second via the use of setInterval() and use clearInterval() to clean up when the component is unmounted.
- Use String.prototype.padStart() to pad each part of the time array to two characters to create the visual representation of the timer.
- If you send random numbers through props, which will run in random timing in each calls.
Component:
import React from 'react';
const CountDown = ({
hours = 0,
minutes = 0,
seconds = 0 }) => {
const [started, setStarted] = React.useState(false);
const [count, setCount] = React.useState(0);
const [[h, m, s], setTime] = React.useState([hours, minutes, seconds]);
const timer = () => {
if (!started) return;
if (h === 0 && m === 0 && s === 0) {
if (count >= 20) { reset(); return; }
restart()
}
else if (m === 0 && s === 0) {
setTime([h - 1, 59, 59]);
} else if (s === 0) {
setTime([h, m - 1, 59]);
} else {
setTime([h, m, s - 1]);
}
};
const start = () => {
setStarted(!started);
if (!started) {
setCount(count + 1);
}
}
const restart = () => {
setTime([parseInt(hours), parseInt(minutes), parseInt(seconds)]);
setStarted(true);
setCount(count + 1);
};
const reset = () => {
setTime([parseInt(hours), parseInt(minutes), parseInt(seconds)]);
setStarted(false);
setCount(0);
};
React.useEffect(() => {
const timerID = setInterval(() => timer(), 1000);
return () => clearInterval(timerID);
});
return (
<div className={'action-container'}>
<button className={'start'} onClick={() => start()}>
{started ? 'Stop' : 'Start'}
</button>
<button className={'start'} onClick={() => reset()}>
Reset
</button>
<div className={'time-panel'}>
<div>
<span>duration: </span>
<span>{`${h.toString().padStart(2, '0')}:${m
.toString()
.padStart(2, '0')}:${s.toString().padStart(2, '0')}`}
` </span >
</div>
<div>
<span>count: </span>
<span>{count}</span>
</div>
</div>
</div>
);
};
export default CountDown;
Example
<CountDown
hours={0}
minutes={1}
seconds={0}
/>
Result