使用 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 按钮和一个重置按钮。
我想在我的应用程序中添加一个计时器,该应用程序是使用 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 按钮和一个重置按钮。