简体   繁体   English

使用 es6 创建带有本机反应的计时器

[英]create timer with react native using es6

I am looking to add a timer to my app which is built using react native.我希望向我的应用程序添加一个计时器,该计时器是使用 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.我已经查看了文档中计时器 mixin的链接,但是我已经使用 es6 构建了应用程序的其余部分,因此这将不兼容。

I have tried the below.我已经尝试了以下。

In my Main class I have a function called getTimerCountDown在我的主类中,我有一个名为getTimerCountDown的函数

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

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

I have tried calling this in componentDidUpdate as shown below.我尝试在componentDidUpdate调用它,如下所示。 This works as I want it to if I don't make any other interactions with the UI.如果我不与 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 再次被调用,conunter 会变得非常快(因为它被调用了 x 次)

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?让倒数计时器在使用 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>
    )
}

I'm not really sure how that would work even without any other UI interactions.即使没有任何其他 UI 交互,我也不确定这将如何工作。 componentDidUpdate is called every time the component is re-rendered, something that happens when the internal state or passed down props have changed.每次重新渲染componentDidUpdate都会调用 componentDidUpdate,当内部状态或传递的 props 发生变化时会发生这种情况。 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?如何将getTimerCountDown移动到您的componentDidMount方法(仅调用一次),然后使用setInterval而不是setTimeout来确保计数器连续递减?

Kinda late, but you can try out this component I made for dealing with timers and es6 components in react-native:有点晚了,但你可以试试我为在 react-native 中处理计时器和 es6 组件而制作的这个组件:

https://github.com/fractaltech/react-native-timer 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);

Try this尝试这个

Timer.js定时器.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应用程序.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 />)
   );
 }

Here is full code how you can create a timer (pomodoro Timer) in react-native;这是如何在 react-native 中创建计时器(番茄钟计时器)的完整代码;

Timer.js定时器.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应用程序.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.这就是我们如何创建一个番茄钟定时器,一个同时具有 WORK TIMER 和 BREAK TIMER 的定时器,它会在其中一个定时器结束时振动手机。 I also added the input functionality ie, 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.我还添加了一个开始/暂停按钮和一个重置按钮。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM