ocetnik / react-native-background-timer

Emit event periodically (even when app is in the background)
MIT License
1.61k stars 225 forks source link

How to stop running the timer when a certain state is reached #177

Open thomasr96 opened 4 years ago

thomasr96 commented 4 years ago

I have a countdown timer for a meditation app implemented as follows

BackgroundTimer.runBackgroundTimer(() => {

      this.props.setMeditationLength(this.props.meditationLength - 1000)
      //stop timer when length is zero
      if (this.props.meditationLength <= 0){
          BackgroundTimer.stopBackgroundTimer();
      }
  }, 1000)

When meditationLength reaches zero, the timer doesn't stop. Additionally, I have a pause button, which is implemented as follows.

<Icon.Button
            name="pause"
            color={(this.state.backgroundColor) ? 'black' : 'grey'}
            size={40}
            backgroundColor="transparent"
            underlayColor="transparent"
            onPress={() => {BackgroundTimer.stopBackgroundTimer();}}>
</Icon.Button>

The pause button somehow stops the timer. What am I doing wrong? Is there a different way to stop the timer from within the BackgroundTimer function?

Thanks

ithustle commented 4 years ago

+1

Oguntoye commented 4 years ago

Did you find anyway out this.

I'm unable to stop the timer when a state is reached also

thomasr96 commented 4 years ago

I honestly never did find a way to stop it. I only had a crappy workaround where I put the stop timer command in the onClick method of the start button I had - right before the new one starts the old timer stops. When the user wants to run another timer, the one that most recently started is the only one being run

W8jonas commented 4 years ago

I found the solution for this problem.

For some reason calling stopBackgroundTimer within a function call in runBackgroundTimer does not work. You need to create another function that contains the condition to execute stopBackgroundTimer. Like a useEffect.

Here is an example code:

const [counter, setCounter] = useState(1)

function increment() {
    // this function run in backgroud
    function timer() {
        contador += counter
        setCounter(contador)
    }
    let contador = 0

    // call timer ever 1000 milliseconds
    BackgroundTimer.runBackgroundTimer(timer, 1000)
}

// execute in render os screen
useEffect(()=>{
    increment()
},[])

// here is the conditional to stop the function
useEffect(()=>{
    if(counter > 10) {
        BackgroundTimer.stopBackgroundTimer()
        return
    }
},[counter])
Oguntoye commented 4 years ago

@W8jonas Can you try explaining the login in the code.. that will make the background timer to stop

YagamiNewLight commented 3 years ago

I found the solution for this problem.

For some reason calling stopBackgroundTimer within a function call in runBackgroundTimer does not work. You need to create another function that contains the condition to execute stopBackgroundTimer. Like a useEffect.

Here is an example code:

const [counter, setCounter] = useState(1)

function increment() {
  // this function run in backgroud
  function timer() {
      contador += counter
      setCounter(contador)
  }
  let contador = 0

  // call timer ever 1000 milliseconds
  BackgroundTimer.runBackgroundTimer(timer, 1000)
}

// execute in render os screen
useEffect(()=>{
  increment()
},[])

// here is the conditional to stop the function
useEffect(()=>{
  if(counter > 10) {
      BackgroundTimer.stopBackgroundTimer()
      return
  }
},[counter])

Didn't work for me