簡體   English   中英

使用 es6 創建帶有本機反應的計時器

[英]create timer with react native using es6

我希望向我的應用程序添加一個計時器,該計時器是使用 React Native 構建的。

我已經查看了文檔中計時器 mixin的鏈接,但是我已經使用 es6 構建了應用程序的其余部分,因此這將不兼容。

我已經嘗試了以下。

在我的主類中,我有一個名為getTimerCountDown的函數

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

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

我嘗試在componentDidUpdate調用它,如下所示。 如果我不與 UI 進行任何其他交互,這將按我的意願工作。

如果我這樣做(例如,我有一個按鈕,我可以單擊視圖。)因為`componentDidUpdate 再次被調用,conunter 會變得非常快(因為它被調用了 x 次)

componentDidUpdate(){
    this.getTimerCountDown();
}

我不確定我是否在這里完全走錯了路,或者對我所做的事情稍作改動就可以得到我想要的東西。 讓倒數計時器在使用 es6 的本機反應中工作的最佳方法是什么?

主頁上的計時器類

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

返回

render(){
    return (
        <View style={styles.container}>
            <Text> This is the Timer : {this.props.setTimer}  - {this.props.timeRem} </Text>
        </View>
    )
}

即使沒有任何其他 UI 交互,我也不確定這將如何工作。 每次重新渲染componentDidUpdate都會調用 componentDidUpdate,當內部狀態或傳遞的 props 發生變化時會發生這種情況。 不是你可以指望每一秒都發生的事情。

如何將getTimerCountDown移動到您的componentDidMount方法(僅調用一次),然后使用setInterval而不是setTimeout來確保計數器連續遞減?

有點晚了,但你可以試試我為在 react-native 中處理計時器和 es6 組件而制作的這個組件:

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

想法很簡單,維護和清除組件上的定時器變量很痛苦,所以簡單地,將它們維護在一個單獨的模塊中。 例子:

// 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);

嘗試這個

定時器.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;

應用程序.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 />)
   );
 }

這是如何在 react-native 中創建計時器(番茄鍾計時器)的完整代碼;

定時器.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
    }
})

應用程序.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',
  },
});

這就是我們如何創建一個番茄鍾定時器,一個同時具有 WORK TIMER 和 BREAK TIMER 的定時器,它會在其中一個定時器結束時振動手機。 我還添加了輸入功能,即,您可以動態更改分鍾和秒的值(無論是工作計時器還是休息計時器)。 我還添加了一個開始/暫停按鈕和一個重置按鈕。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM