2

i want to set countdown timer start at 00:00 and repeated every 5 minute.(example: when time is 00:05 timer is countdown 5 minutes until 00:10, and in 00:10 countdown 5 minute again, and so on)

this is my code now :

  class App extends React.Component {
   constructor(props) {
   super(props);
    this.state = {
    minutes: 5,
    seconds: 0
  };
 }

 ...............

    componentDidMount() {
      this.getData();

      this.myInterval = setInterval(() => {
        const { seconds, minutes } = this.state
        if (seconds > 0) {
          this.setState(({ seconds }) => ({
            seconds: seconds - 1
          }))
        }
        if (seconds === 0) {
          if (minutes === 0) {
            clearInterval(this.myInterval)
          } else {
            this.setState(({ minutes }) => ({
              minutes: minutes - 1,
              seconds: 59
            }))
          }
        }
      }, 1000)

    }

 ...........

 return (
   <p>Countdown : {this.state.minutes}:{this.state.seconds < 10 ? `0${this.state.seconds}` : this.state.seconds} </p>

    );
  }
}

where i should change or add to make this countdown start at 00:00 and repeated every 5 minute. anyone can help me?

1
  • So you basically want a setInterval callback that counts down every second (1000ms) for 300 seconds and resets itself? I'm not quite understanding the at 00:05 countdown to 00:10, how does one count down from 5 to 10? Commented Aug 14, 2020 at 8:53

3 Answers 3

6

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>);
}
Sign up to request clarification or add additional context in comments.

Comments

3

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} />;
};

Edit set-countdown-timer-react-js

Comments

-2
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>
    )
}

1 Comment

Code only answers are great but not encouraged. Try adding some explanation about how this code works.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.