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?