如何运行一系列倒数时钟
How to run a series of Count Down Clock
我正在尝试 运行 从一个数组中进行多次倒计时,例如 [11, 12, 13, 14, 15, 16]。我想要实现的是,第一次将倒计时设置为11,当它达到0时,定时器设置为12然后倒计时为0。之后,重置为13并倒计时,然后重置为14和倒计时等
但是,我的代码只能从11倒数到0,然后停止。 For 循环似乎不起作用,并且永远不会将第二个项目 12 放入计时器中。后来发现是因为for循环里面的retun在循环外break了。我想知道是否有一些聪明的方法可以避免在 For 循环中使用 return?或者,如何在不跳出循环的情况下在 For-Loop 中使用 Return?
(我有另一个计数器叫做 TotalTime,我打算计算它花费的所有总时间,即 11+12+13+14 等)
定时器和显示屏:
import {View, Text, StyleSheet, FlatList} from 'react-native';
import PlaySounds from './PlaySounds';
const CustomTimer = ({time, length}) => {
const [seconds, setSeconds] = useState(time);
const [totalTime, setTotalTime] = useState(0);
useEffect(() => {
if (seconds > 0 )
{ const interval = setInterval(() => {
setSeconds(seconds => seconds - 1);
setTotalTime(seconds=>seconds + 1)
}, 1000);
return () => clearInterval(interval);
}}, [seconds])
return (
<View>
<Text style={{fontSize:20}}> Count Down: {seconds} sec</Text>
<Text style={{fontSize:20}}> Total Time: {totalTime} sec</Text>
</View>
)}
export default CustomTimer;
=====================
import React, {useEffect, useState} from 'react';
import {SafeAreaView,View,Button,ScrollView, Text, StyleSheet} from 'react-native';
import CustomTimer from '../component/CustomTimer';
const BrewScreen = () => {
const timeArray= [11, 12, 13, 14, 15, 16]
const length = timeArray.length
const countDownArray=() =>{
for (let i=0; i<length; i++) {
return(<CustomTimer time={timeArray[i]} length={length}/>)
}
}
return (
<>
<ScrollView>
{countDownArray()}
</ScrollView>
</>
)
}
问题似乎是您 return 在 for 循环中。
这意味着在 countDownArray 函数中 for 循环的第一次迭代期间,您 return Timer 元素。当您这样做时,该函数将退出,因此循环将不会继续。
要实现所需的行为,您需要的是另一种创建 Timer 元素的方法。这可能需要 Timer 元素中的回调函数。这可用于更新 BrewScreen 的状态,并更新显示的计时器。
我终于解决了,不是使用循环,而是强大的 useEffect:
const CustomTimer = ({time}) => {
const [seconds, setSeconds] = useState(time[0]);
const [count, setCount] = useState(1)
const [totalTime, setTotalTime] = useState(0);
useEffect(() => {
if (seconds >= 0 )
{ const interval = setInterval(() => {
setSeconds(seconds => seconds - 1);
setTotalTime(seconds=> seconds + 1)
console.log('seconds ', seconds, ' totalTime ', totalTime)
}, 1000);
return () => clearInterval(interval);}
else if (count<(time.length)) {
setCount(count => count+1)
setSeconds(time[count])}
else return
}
)
return (
<View>
<Text style={{fontSize:20}}> Count Down: {seconds} sec</Text>
<Text style={{fontSize:20}}> Total Time: {totalTime} sec</Text>
{seconds===3?<PlaySounds/>:null}
</View>
)}
- 在 For 循环中有 Return 将跳出循环
- JS 会一次性执行所有的 i 所以你需要添加 Async/Await 对
的 Promise
- Return 不会中断 ForEach 循环
- 但是,Async 在 ForEach 循环中不起作用
- useEffect 自动 运行 适当支持时间间隔的循环
- 在我想要 运行 一个 count-down 时钟的情况下,setInterval 必须优先于 setCountDown,因为 setInterval 会在您指定的每毫秒更新一次。
- 记得用 clearInterval
清理你的间隔
- 有一件事我不明白:count的初始值必须是1而不是0。好像count在第一次读取时被强制设置为初始值。如果我把它初始化为0,数组中的第一个数字将被执行两次。
- 另外,倒计时最后显示的数字是-1....我知道这是因为useEffect是这样停止的,但想知道如何避免显示负数?
我正在尝试 运行 从一个数组中进行多次倒计时,例如 [11, 12, 13, 14, 15, 16]。我想要实现的是,第一次将倒计时设置为11,当它达到0时,定时器设置为12然后倒计时为0。之后,重置为13并倒计时,然后重置为14和倒计时等
但是,我的代码只能从11倒数到0,然后停止。 For 循环似乎不起作用,并且永远不会将第二个项目 12 放入计时器中。后来发现是因为for循环里面的retun在循环外break了。我想知道是否有一些聪明的方法可以避免在 For 循环中使用 return?或者,如何在不跳出循环的情况下在 For-Loop 中使用 Return?
(我有另一个计数器叫做 TotalTime,我打算计算它花费的所有总时间,即 11+12+13+14 等)
定时器和显示屏:
import {View, Text, StyleSheet, FlatList} from 'react-native';
import PlaySounds from './PlaySounds';
const CustomTimer = ({time, length}) => {
const [seconds, setSeconds] = useState(time);
const [totalTime, setTotalTime] = useState(0);
useEffect(() => {
if (seconds > 0 )
{ const interval = setInterval(() => {
setSeconds(seconds => seconds - 1);
setTotalTime(seconds=>seconds + 1)
}, 1000);
return () => clearInterval(interval);
}}, [seconds])
return (
<View>
<Text style={{fontSize:20}}> Count Down: {seconds} sec</Text>
<Text style={{fontSize:20}}> Total Time: {totalTime} sec</Text>
</View>
)}
export default CustomTimer;
=====================
import React, {useEffect, useState} from 'react';
import {SafeAreaView,View,Button,ScrollView, Text, StyleSheet} from 'react-native';
import CustomTimer from '../component/CustomTimer';
const BrewScreen = () => {
const timeArray= [11, 12, 13, 14, 15, 16]
const length = timeArray.length
const countDownArray=() =>{
for (let i=0; i<length; i++) {
return(<CustomTimer time={timeArray[i]} length={length}/>)
}
}
return (
<>
<ScrollView>
{countDownArray()}
</ScrollView>
</>
)
}
问题似乎是您 return 在 for 循环中。
这意味着在 countDownArray 函数中 for 循环的第一次迭代期间,您 return Timer 元素。当您这样做时,该函数将退出,因此循环将不会继续。
要实现所需的行为,您需要的是另一种创建 Timer 元素的方法。这可能需要 Timer 元素中的回调函数。这可用于更新 BrewScreen 的状态,并更新显示的计时器。
我终于解决了,不是使用循环,而是强大的 useEffect:
const CustomTimer = ({time}) => {
const [seconds, setSeconds] = useState(time[0]);
const [count, setCount] = useState(1)
const [totalTime, setTotalTime] = useState(0);
useEffect(() => {
if (seconds >= 0 )
{ const interval = setInterval(() => {
setSeconds(seconds => seconds - 1);
setTotalTime(seconds=> seconds + 1)
console.log('seconds ', seconds, ' totalTime ', totalTime)
}, 1000);
return () => clearInterval(interval);}
else if (count<(time.length)) {
setCount(count => count+1)
setSeconds(time[count])}
else return
}
)
return (
<View>
<Text style={{fontSize:20}}> Count Down: {seconds} sec</Text>
<Text style={{fontSize:20}}> Total Time: {totalTime} sec</Text>
{seconds===3?<PlaySounds/>:null}
</View>
)}
- 在 For 循环中有 Return 将跳出循环
- JS 会一次性执行所有的 i 所以你需要添加 Async/Await 对 的 Promise
- Return 不会中断 ForEach 循环
- 但是,Async 在 ForEach 循环中不起作用
- useEffect 自动 运行 适当支持时间间隔的循环
- 在我想要 运行 一个 count-down 时钟的情况下,setInterval 必须优先于 setCountDown,因为 setInterval 会在您指定的每毫秒更新一次。
- 记得用 clearInterval 清理你的间隔
- 有一件事我不明白:count的初始值必须是1而不是0。好像count在第一次读取时被强制设置为初始值。如果我把它初始化为0,数组中的第一个数字将被执行两次。
- 另外,倒计时最后显示的数字是-1....我知道这是因为useEffect是这样停止的,但想知道如何避免显示负数?