Play/Pause Button Doesn't Work

This is the logic behind my ‘play/pause’ functionality. Does anyone know why it isn’t working? The timer seems to spasm out whenever I click the button. Much help would be appreciated!

  const [onBreak, setOnBreak] = useState(false) 
  const [isPlaying, setIsPlaying] = useState(false)

  useEffect(() => {
    const timerFunc = setInterval(() => {
    setIsPlaying(!isPlaying)
    if (!onBreak) {
      if (sessionSec === 0 && sessionMin !== 0) {
        setSessionSec(59)
        setSessionMin(sessionMin - 1)
      } else if (sessionSec !== 0 && sessionMin !== 0)  {
         setSessionSec(sessionSec - 1)
      } else if (sessionSec === 0 && sessionMin === 0) {
        setOnBreak(true)
      }
    } else if (onBreak) {
        if (breakSec === 0 && breakMin !== 0) {
        setBreakSec(59)
        setBreakMin(breakMin - 1)
      } else if (breakSec !== 0 && breakMin !== 0) {
         setBreakSec(breakSec - 1)
      } else if (breakSec === 0 && breakMin === 0) {
        setOnBreak(false)
      }
    } else {
  clearInterval(timerFunc)
  }
  }, 100);
  }, [isPlaying]);

    <button onClick={() => setIsPlaying(!isPlaying)}>{isPlaying ? 'Pause': 'Play'}</button>

I can post all the code if you need :slight_smile:

It would be better if you posted a link to the project and source code, such as if you have it in codepen or github.

1 Like

Sure thing: https://codepen.io/ErcDz/pen/oNGJryP?editors=0010

A few things to point out:

  • Why are you calling setIsPlaying(!isPlaying) at the very beginning of the setInterval callback? What do you think this does?
  • You are using the variable onBreak to make a decision in that call back but I don’t see anywhere in your code where you modify this variable.

Thank you for the reply!

  1. This is so that on line 83, a message will display either ‘Play’ or ‘Pause’ depending on whether you click it the first time (meaning isPlaying is set to true and thus ‘Pause’ is displayed).

  2. On line 40 and 49, I modify onBreak so that the code on 79-81 can display the correct message.

For 1, setIsPlaying changes the value of isPlaying, so every second you are toggling the value of isPlaying. I don’t think this is what you want to do. This value should only be set when either the play/pause or reset button is clicked, right?

  1. Sorry, I overlooked that.

I think you need to reconsider how you are handling the timer countdown. You should probably have a separate state variable for the countdown. Also, useEffect is creating a new setInterval every time but you aren’t clearing the old one. So every time you pause/play you are adding a new timer.

Could you give me an example (not necessarily the answer) to how this would look like? I followed this StackOverflow (javascript - how to get an useEffect inside a function in React? - Stack Overflow) answer to get the format I got to. Here is the SOF answer I followed:

import './App.css';
import React, { useEffect, useState } from 'react';

function App() {
  const time = 20;
  const [count, setCount] = useState(time);
  const [isStart, setIsStart] = useState(false);


    useEffect(() => {
      if (isStart) {
        const timer = setInterval(() => {
          if (count > 0) {
            setCount(count - 1)
          } else {
            setCount('Times up');
            clearInterval(timer);
          }
        }, 1000);
      }
    }, [isStart]);


  return (
    <div className="App">
      <div>{count}</div>
      <button onClick={() => setIsStart(true)}> start </button>
      <button> pauze </button>
    </div>
  );
}

export default App;

Was this a good format to follow? And if so, how does it differ from my answer?

Thank you for your patience by the way, I’ve been stuck on this timer functionality for quite some time and was lost.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.