0

I've made pomodore timer using class component. Now I want to convert it into a function component. Here is what I have at this point.

function App() {
  const [time, setTime] = useState(null);
  const [isRunning, setIsRunning] = useState(false);
  const [session, setSession] = useState("work");
  const [countdownID, setCountdownID] = useState(null);
  const [streak, setStreak] = useState(0);
  // TODO - settings
  const [workTime, setWorkTime] = useState(10);
  const [breakTime, setBreakTime] = useState(5);
  const [longBreakTime, setLongBreakTime] = useState(20);

  // USE EFFECTS
  useEffect(() => {
    setTime(workTime);
  }, []);

  // FUNCTIONS
  const counter = () => {
    if (time === 0) {
      if (session === "work") {
        if (streak < 3) {
          setTime(breakTime); // short break
          setSession("break");
          setStreak((streak) => streak + 1);
        } else {
          setTime(longBreakTime); // long break
          setSession("break");
          setStreak(0);
        }
      } else if (session === "break") {
        stopCounter();
        setTime(workTime);
        setSession("work");
      }
    } else {
      setTime((time) => time - 1);
    }
    console.log(time);
  };

  const startCounter = () => {
    let countdownID = setInterval(counter, 1000);
    setCountdownID(countdownID);
    setIsRunning(true);
  };

  const stopCounter = () => {
    clearInterval(countdownID);
    setIsRunning(false);
  };

  const resetCounter = () => {
    if (session === "work") {
      clearInterval(countdownID);
      setTime(workTime);
      setSession("break");
      setIsRunning(false);
    } else {
      // skipping break
      clearInterval(countdownID);
      setTime(workTime);
      setSession("work");
      setIsRunning(false);
    }
  };

  return (
    <>
      <Timer
        time={time}
        isRunning={isRunning}
        startCounter={startCounter}
        stopCounter={stopCounter}
        resetCounter={resetCounter}
      />
      <Streak streak={streak} />
    </>
  );
}

export default App;

The problem is that setTime((time) => time - 1); doesn't seem to work as intended and updates only visual representation of timer in Timer component. The countdown also doesn't stop at 00:00 and negative numbers show up. That's probably because when I console.log(time) I always get the initial 10, which was assigned using useEffect. How to make setTime update the state properly?

piotrparaf
  • 13
  • 4

0 Answers0