Reputation: 61
I am trying to run multiple count-down from an array, e.g., [11, 12, 13, 14, 15, 16]. What I would like to achieve is that the first time set count down time to 11, when it reach 0, the timer is set to 12 and then count down to 0. After that, reset to 13 and count down, then reset to 14 and count down, etc.
However, my code can only count down from 11 to 0, and then stop. For loop seems not working and never put the second item 12 into the timer. I later found out it is because the retun inside for loop break it outside of the loop. I wonder if there are some smart ways to avoid return in a For-Loop? Or, how to use Return in For-Loop without breaking out of the loop?
(I have another counter there called TotalTime which I inteneded to count all the total time it takes, ie, 11+12+13+14,etc)
The Timer and Display Screen:
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>
</>
)
}
Upvotes: 0
Views: 372
Reputation: 61
I finally solve it, not using loops but the all mighty 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>
)}
Upvotes: 1
Reputation: 121
The issue seems to be that you return inside the for loop.
This means that during the first iteration of the for loop in the countDownArray function you return the Timer element. When you do this, the function will exit and so the loop will not continue.
What you would need instead to achieve your desired behaviour is a different way of creating the Timer elements. This will likely require a callback function in the Timer element. This can be used to update the state of the BrewScreen, and update the Timer displayed.
Upvotes: 1