Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

create timer with react native using es6

I am looking to add a timer to my app which is built using react native.

I have looked at the link to the timer mixin in the documentation however I have built the rest of the app using es6 so this won't be compatible.

I have tried the below.

In my Main class I have a function called getTimerCountDown

getTimerCountDown() {
    setTimeout(() => {
      this.setTimeRemaining(this.getTimeRem()-1);
    }, 1000);
}

getTimeRem() {
    return this.state.timeRemaining;
}

I have tried calling this in componentDidUpdate as shown below. This works as I want it to if I don't make any other interactions with the UI.

If I do (eg I have a button I can click on the view.) as `componentDidUpdate gets called again the conunter gets really quick (as it is getting called x number of times)

componentDidUpdate(){
    this.getTimerCountDown();
}

I am not sure if I am completly on the wrong track here or a small change to what I have done can get me what I want. What is the best way to get a countdown timer working in react native using es6?

Timer Class on main page

<Timer timeRem={this.getTimeRem()} />

returns

render(){
    return (
        <View style={styles.container}>
            <Text> This is the Timer : {this.props.setTimer}  - {this.props.timeRem} </Text>
        </View>
    )
}
like image 516
ak85 Avatar asked Aug 12 '15 11:08

ak85


People also ask

How do I set a timer in react native?

Show activity on this post. import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; import Timer from './timer'; export default function App() { return ( <View style={styles. container}> <Timer /> </View> ); } const styles = StyleSheet.

How do I start and stop a timer in react native?

Start and Clear button will active once you click on Stop button. Stop button will stop the timer without reseting the time. Clear button will reset the timer.

What is requestAnimationFrame react native?

The requestAnimationFrame method returns an integer ID which can be used to cancel the queued request using the cancelAnimationFrame(id) method. The animation callback function can also accept a timestamp value, which is the time elapsed in milliseconds since the web page was loaded.


4 Answers

Here is full code how you can create a timer (pomodoro Timer) in react-native;

Timer.js

import React from 'react'
import {Vibration, View, Button, Text, TextInput, StyleSheet} from 'react-native'


let pomInterval;

export default class Timer extends React.Component {
    constructor() {
        super();
        this.state = {
            minutes: 5,
            seconds: 0,
            workmins: 5,
            worksecs: 0,
            breakMins: 2,
            breakSecs: 0,
            timerState: 'WORK TIMER',
            btnState: 'Start'
        }
    }

    vibrate = () => {
        Vibration.vibrate([500, 500, 500])
    }

    pomTimer = () => {
        pomInterval = setInterval(() => {
            let newSec = this.state.seconds;
            newSec--;
            if(newSec < 0) {
                newSec = 59;
                this.state.minutes--;
            }
            this.setState({
                seconds: newSec,
            })

            if(newSec <= 0 && this.state.minutes <= 0) {
                this.vibrate();
                if(this.state.timerState == 'WORK TIMER') {
                    this.setState({
                        timerState: 'BREAK TIMER',
                        minutes: this.state.breakMins,
                        seconds: this.state.breakSecs
                        
                    })
                }else {
                    this.setState({
                        timerState: 'WORK TIMER',
                        minutes: this.state.workmins,
                        seconds: this.state.worksecs
                    })
                }
            }
        }, 1000);
    }


    changeWorkMin = mins => {
        clearInterval(pomInterval);
        this.setState({
            minutes: mins || 0,
            workmins: mins || 0,
            btnState: 'Start'
        })
    }

    changeWorkSec = secs => {
        clearInterval(pomInterval);
        this.setState({
            seconds: secs || 0,
            worksecs: secs || 0,
            btnState: 'Start'
        })
    }

    changeBreakMin = mins => {
        clearInterval(pomInterval);
        this.setState({
            breakMins: mins || 0,
            btnState: 'Start'
        })
    }

    changeBreakSec = secs => {
        clearInterval(pomInterval);
        this.setState({
            breakSecs: secs || 0,
            btnState: 'Start'
        })
    }

    // Creating the functionality for the pause/start button
    chnageBtnState = () => {
        if(this.state.btnState == 'Start') {
            this.pomTimer();
            this.setState({
                btnState: 'Pause'
            })

        }else {
            clearInterval(pomInterval);
            this.setState({
                btnState: 'Start'
            })
        }
    }

    // Creating the functionality for the reset button
    reset = () => {
        clearInterval(pomInterval);
        if(this.state.timerState == 'WORK TIMER') {
            this.setState({
                minutes: this.state.workmins,
                seconds: this.state.worksecs,
                btnState: 'Start'
            })
        }else {
            this.setState({
                minutes: this.state.breakMins,
                seconds: this.state.breakSecs,
                btnState: 'Start'
            })
        }
    }

    render() {
        return (
            <View style={styles.viewStyles}>
                <Text style={styles.textStyles}>{this.state.timerState}</Text>
                <Text style={styles.textStyles}>{this.state.minutes}:{this.state.seconds}</Text>
                <Text>
                    <Button title={this.state.btnState} onPress={this.chnageBtnState} />
                    <Button title='Reset' onPress={this.reset} />
                </Text>
                <Text>Work Time:</Text>
                <TextInput style={styles.inputStyles} value={this.state.workmins.toString()} placeholder='Work Minutes' onChangeText={this.changeWorkMin} keyboardType='numeric' />
                <TextInput style={styles.inputStyles} value={this.state.worksecs.toString()} placeholder='Work Seconds' onChangeText={this.changeWorkSec} keyboardType='numeric' />
                <Text>Break Time:</Text>
                <TextInput style={styles.inputStyles} value={this.state.breakMins.toString()} placeholder='Break Minutes' onChangeText={this.changeBreakMin} keyboardType='numeric' />
                <TextInput style={styles.inputStyles} value={this.state.breakSecs.toString()} placeholder='Break Seconds' onChangeText={this.changeBreakSec} keyboardType='numeric' />
            </View>
        )
    }
}

// Creating a style sheet to write some styles
const styles = StyleSheet.create({
    viewStyles: {
        alignItems: 'center'
    },

    textStyles: {
        fontSize: 48
    },

    inputStyles: {
        paddingHorizontal: 50,
        borderColor: 'black',
        borderWidth: 1
    }
})

App.js

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Timer from './timer';

export default function App() {
  return (
    <View style={styles.container}>
      <Timer />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

This is how we can create a pomodoro timer, a timer which has both WORK TIMER and BREAK TIMER and it vibrates the phone as one of the timer reaches its end. I also added the input functionality i.e, you can dynamically change the value of the minutes and seconds (whether work timer or break timer is going on). I also added a start/pause button and a reset button.

like image 115
Irfan wani Avatar answered Oct 21 '22 02:10

Irfan wani


Try this

Timer.js

import React, { Component } from "react";
import { View,Text,Button,StyleSheet } from "react-native";
const timer = () => {};
class Timer extends Component {
    constructor(props) {
    super(props);
    this.state = {
      remainingTime: 10
     };
    }

 countdownTimer(){
   this.setState({remainingTime:10 });
   clearInterval(timer);
   timer = setInterval(() =>{
        if(!this.state.remainingTime){
          clearInterval(timer);
          return false;
        }
        this.setState(prevState =>{
        return {remainingTime: prevState.remainingTime - 1}});
        },1000);
    }

    render() {
      return (
       <View style={styles.container}>
         <Text>Remaining time :{this.state.remainingTime}</Text>
          <Button title ="Start timer" onPress={()=>this.countdownTimer()}/>
       </View>
     );
   }
  }


  const styles = StyleSheet.create({
    container:{
     flex:1,
     justifyContent:'center',
     alignItems:'center',
   } 
});

  export default Timer;

App.js

import React, { Component } from "react";
  import { View,Text,Button,StyleSheet } from "react-native";
  import Timer from './timer';

  export default class App extends Component{
   render(
    return (<Timer />)
   );
 }
like image 31
Akash sharma Avatar answered Oct 21 '22 02:10

Akash sharma


I'm not really sure how that would work even without any other UI interactions. componentDidUpdate is called every time the component is re-rendered, something that happens when the internal state or passed down props have changed. Not something you can count on to happen exactly every second.

How about moving the getTimerCountDown to your componentDidMount method (which is only called once), and then using setInterval instead of setTimeout to make sure the counter is decremented continuously?

like image 23
tkers Avatar answered Oct 21 '22 01:10

tkers


Kinda late, but you can try out this component I made for dealing with timers and es6 components in react-native:

https://github.com/fractaltech/react-native-timer

Idea is simple, maintaining and clearing timer variables on the components is a pain, so simply, maintain them in a separate module. Example:

// not using ES6 modules as babel has broken interop with commonjs for defaults 
const timer = require('react-native-timer');

// timers maintained in the Map timer.timeouts 
timer.setTimeout(name, fn, interval);
timer.clearTimeout(name);

// timers maintained in the Map timer.intervals 
timer.setInterval(name, fn, interval);
timer.clearInterval(name);

// timers maintained in the Map timer.immediates 
timer.setImmediate(name, fn);
timer.clearImmediate(name);

// timers maintained in the Map timer.animationFrames 
timer.requestAnimationFrame(name, fn);
timer.cancelAnimationFrame(name);
like image 28
kapv89 Avatar answered Oct 21 '22 02:10

kapv89