Home > Enterprise >  setState not applying changes in React function component
setState not applying changes in React function component

Time:10-23

Im trying to do a Pomodoro Clock timer, which is basically two timers that alternate between. Thats all the code:

import React, { useState } from "react";

function Challenge20() {
    const [timer, setTimer] = useState('');
    let minutes = 0;
    let seconds = 0;
    const [workRest, setWorkRest] = useState('work');


function startTimer() {
    document.getElementById('start').style.display = 'none';
    minutes = document.getElementById('work').value - 1;
    seconds = 59;
    setInterval(reduceSeconds, 1000);
};

function reduceSeconds() {
    
    if (seconds < 10) {
        setTimer(minutes   ':'   '0'   seconds);
    }
    else {
        setTimer(minutes   ':'   seconds);
    }

    seconds -= 1;

    if (seconds < 1 && minutes > 0) {
        seconds = 59;
        minutes -= 1;
    }
    else if (seconds == 0  && minutes == 0){
        setWorkRest(workRest == 'work' ? 'rest' : 'work');
        minutes = document.getElementById(workRest == 'work' ? 'work' : 'rest').value;
    }
};

return (
    <>  
        <label>Work Minutes:</label>
        <input id='work' type='number' max='60'/>
        <br/>
        <label>Rest Minutes:</label>
        <input id='rest' type='number' max='60'/>
        <br/>
        <br/>
        <span id='timer'>{workRest} -&gt; {timer}</span>
        <button id='start' onClick={() => startTimer()}>Start!</button>
    </>
);
};

export default Challenge20;

The problem is in this part:

else if (seconds == 0  && minutes == 0){
            setWorkRest(workRest == 'work' ? 'rest' : 'work');
            minutes = document.getElementById(workRest == 'work' ? 'work' : 'rest').value;
        }

The setState is not changing from 'work' to 'rest', also tried to call a function to change the state, clearing interval and 2 separated if, nothing worked, what am I doing wrong?

CodePudding user response:

I think this is what you're trying to achieve? The problem is that the timer keeps going. On the next iteration, it sets workRest back to its previous value. To solve this, I used clearInterval to stop iterating, and decremented seconds to display 00:00 on the timer. As such, I had to assign the interval creation to a variable we can pass into clearInterval.

import React, { useState } from "react";

function Challenge20() {
  const [timer, setTimer] = useState("");
  let minutes = 0;
  let seconds = 0;
  const [workRest, setWorkRest] = useState("work");
  let interval;
  function startTimer() {
    document.getElementById("start").style.display = "none";
    minutes = document.getElementById("work").value - 1;
    seconds = 59;
    interval = setInterval(reduceSeconds, 1);
  }

  function reduceSeconds() {
    if (seconds < 10) {
      setTimer(minutes   ":"   "0"   seconds);
    } else {
      setTimer(minutes   ":"   seconds);
    }

    seconds -= 1;

    if (seconds < 1 && minutes > 0) {
      seconds = 59;
      minutes -= 1;
    } else if (seconds == 0 && minutes == 0) {
      console.log();
      setWorkRest(workRest == "work" ? "rest" : "work");
      minutes = document.getElementById(workRest == "work" ? "work" : "rest")
        .value;
      clearInterval(interval);
      seconds -= 1;
    }
  }

  return (
    <>
      <label>Work Minutes:</label>
      <input id="work" type="number" max="60" />
      <br />
      <label>Rest Minutes:</label>
      <input id="rest" type="number" max="60" />
      <br />
      <br />
      <span id="timer">
        {workRest} -&gt; {timer}
      </span>
      <button id="start" onClick={() => startTimer()}>
        Start!
      </button>
    </>
  );
}

CodePudding user response:

useState is not work inside the condition. For ex: you are set the state value in the if condition. State value not updated in condition.

  • Related