Countdown Timer to 5 Minutes from Current Date

new to react here. I'm trying to output a countdown timer to a date that is set to 5 minutes from now. But all I was able to get was either the countdown rubber banding, or static on 5 minutes or 0. Currently, it is static on 00:00:00:00. Thanks

EDIT: I'm trying to make it work with hooks instead of through a constructor class.

import AButton from './aButton'; import { useState, useRef, useEffect} from 'react';

export default function Countdown() {
        
        const [addTime, setAddtime] = useState();
        const [countdown, setCountdown] = useState((new Date()).toLocaleTimeString());

        const [timerDays, setDays] = useState('00');
        const [timerHours, setHours] = useState('00');
        const [timerMinutes, setMinutes] = useState('00');
        const [timerSeconds, setSeconds] = useState('00');

        let interval = useRef();

        const oldDateObject = new Date();
        const sourceDate = oldDateObject.getTime(); // date - 300000
        const diff = 5;
        //this gives use the unix timestamp of the future date which is the current date + 5 minutes
        const futureDate = new Date(oldDateObject.getTime() + diff*60000); //300000
        

        const convertToDate = (date, hours, minutes, seconds) => {
                
        
        date = new Date(sourceDate * 1000);
        // Hours part from the timestamp
        hours = date.getHours();
        // Minutes part from the timestamp
        minutes = ("0" + date.getMinutes()).substr(-2);
        // Seconds part from the timestamp
        seconds = ("0" + date.getSeconds()).substr(-2);

        return hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
        }

        const startTimer = () => {
                const timeUpdate = new Date().getTime(convertToDate);
        interval = setInterval(() => {  
        const now = new Date().getTime();
        const timeDifference = timeUpdate - now;
        
        //this converts the unix code of the future date to each clock element every second
        const days = Math.floor(timeDifference / (24 * 60 * 60 * 1000));
        const hours = Math.floor(timeDifference % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));;
        const minutes = Math.floor(timeDifference % (60 * 60 * 1000) / (60 * 1000));;
        const seconds = Math.floor(timeDifference % (60 * 1000) / 1000);;
        

        if (timeDifference < 0) {
                clearInterval(interval.current);
        } else {
                setDays(days);
                setHours(hours);
                setMinutes(minutes);
                setSeconds(seconds);
        }

        }, 1000);
};

useEffect(() => {
        startTimer();
        return () => { clearInterval(interval.current); 
        };
});
        
        return (
        <div>
        <h1>{countdown === null ? <span style={{padding: '50px'}}></span> : countdown}</h1>
        <button onClick={ () => setCountdown(countdown !== null ? null : ( new Date()).toLocaleTimeString())}>{countdown === null ? 'Show' : 'Hide'}</button>
        <div>----------------</div>
        <h1>{timerDays} : {timerHours} : {timerMinutes} : {timerSeconds}</h1>
        <button>Activate countdown</button>
        </div>
        )
}
1

2 Answers

I think you are making it way more complicated than it needs to be.

Store a state of a 5 minute countdown (in seconds) and a second piece of state to start/run the timer.

When the timer is started seed the countdown state with 5 minutes (it will expire from the current point in time).

Compute the derived and formatted time from the single countdown state.

function App() {
  const [countDown, setCountDown] = React.useState(0);
  const [runTimer, setRunTimer] = React.useState(false);

  React.useEffect(() => {
    let timerId;

    if (runTimer) {
      setCountDown(60 * 5);
      timerId = setInterval(() => {
        setCountDown((countDown) => countDown - 1);
      }, 1000);
    } else {
      clearInterval(timerId);
    }

    return () => clearInterval(timerId);
  }, [runTimer]);

  React.useEffect(() => {
    if (countDown < 0 && runTimer) {
      console.log("expired");
      setRunTimer(false);
      setCountDown(0);
    }
  }, [countDown, runTimer]);

  const togglerTimer = () => setRunTimer((t) => !t);

  const seconds = String(countDown % 60).padStart(2, 0);
  const minutes = String(Math.floor(countDown / 60)).padStart(2, 0);

  return (
    <div className="App">
      <div>
        Time: {minutes}:{seconds}
      </div>

      <button type="button" onClick={togglerTimer}>
        {runTimer ? "Stop" : "Start"}
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
    <App />,
  rootElement
);
.App {
  font-family: sans-serif;
  text-align: center;
}
<script src=""></script>
<script src=""></script>
<div id="root"></div>
3

look at

Countdown timer in React

and

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.

Share this article
Twitter Facebook Pinterest