M
M
Marat Shakirov2021-10-25 17:56:53
React
Marat Shakirov, 2021-10-25 17:56:53

Why is the updated state not passed to the interval?

Pomodoro timer . With each update of the state of the timer in the interval, for some reason, the initial value of the timer is transmitted when I just started the timer. And it turns out that the checks for (timer === 0 ....) do not pass, because in the interval the timer (value) is always the same (although it is updated). Why is this happening and how to make it so that after every second passed in the interval there is an updated value of the timer ??? (The code is not all, but only the part where the problem is visible)

export const App = () => {
  const [breakLength, setBreakLength] = useState(5);
  const [sessionLength, setSessionLength] = useState(25);
  const [mode, setMode] = useState('Session');
  const [timer, setTimer] = useState(3);
  const [timerRunning, setTimerRunning] = useState(false);

const countDownTimer = () => {
    clearInterval(countdown);
    
    countdown = setInterval(() => {
      if (timer === 0 && mode === 'Session') {
        setMode('Break');
        setTimer(breakLength * 60 + 1);
      }
    
      if (timer === 0 && mode === 'Break') {
        setMode('Session');
        setTimer(sessionLength * 60 + 1);
      }
      setTimer(prevState => prevState - 1);

    }, 1000);

    setTimerRunning(true);

  };


return (
<Button
              id="start_stop"
              onClick={() => {
                countDownTimer();
              }}
              icon={<FaPlay className="fa fa-play" />}
            >
)

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vladimir, 2021-10-25
@Casufi

setInterval will not work with the state as you wrote, I’m not sure why you need the current interval in the state at all, if everything happens within the framework of one function,
countdown is taken from the ceiling
If any of the variables in the state changes, you need to use useEffect and recreate the timer with new variables.
If a state needs to be used, I would prefer setTimeout

B
bitwheeze, 2021-10-25
@bitwheeze

I'm not an expert, maybe I'm lying. Your "export const App" is a function that runs every time the component needs to be re-rendered. In one of these calls, you create a timer and pass it an arrow function that will be called at the specified frequency. After the App function creates a timer with this function of yours, it will finish its work and the entire state of the stack, along with the variables, will go to nirvana. Then when the timer calls your arrow function, it simply has nowhere to take the data. At best, it will still have access to the values ​​it had when the timer was created.
The state will change already in another call to the App function, that arrow timer function knows nothing about it.
I don't understand what you want to show there. Maybe you should look for the useDebounce hook.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question