使用 es6 与本机反应创建计时器

create timer with react native using es6

我想在我的应用程序中添加一个计时器,该应用程序是使用 React Native 构建的。

我查看了文档中的 link 到 timer mixin,但是我使用 es6 构建了应用程序的其余部分,因此这不兼容。

我试过下面的方法。

在我的 Main class 中,我有一个名为 getTimerCountDown

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

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

我试过在 componentDidUpdate 中调用它,如下所示。如果我不与 UI.

进行任何其他交互,这将按照我的意愿工作

如果我这样做(例如,我有一个按钮,我可以点击视图。)当再次调用 `componentDidUpdate 时,计数器会变得非常快(因为它被调用 x 次)

componentDidUpdate(){
    this.getTimerCountDown();
}

我不确定我是否完全走错了路,或者对我所做的事情稍作改变就能得到我想要的东西。 使用 es6 让倒数计时器在本机反应中工作的最佳方法是什么?

计时器Class 在主页上

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

returns

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

即使没有任何其他 UI 交互,我也不确定它如何工作。每次重新渲染组件时都会调用 componentDidUpdate,这是在内部状态或传递的道具发生变化时发生的事情。不是你可以指望每一秒都会发生的事情。

如何将 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);

试试这个

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

这里是完整的代码,你可以如何在 react-native 中创建一个定时器(pomodoro Timer);

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',
  },
});

这就是我们如何创建一个番茄钟计时器,一个同时具有工作计时器和休息计时器的计时器,它会在其中一个计时器结束时振动 phone。我还添加了输入功能,即您可以动态更改分钟和秒的值(工作计时器或休息计时器是否正在进行)。我还添加了一个 start/pause 按钮和一个重置按钮。