问题
Every element of the array should be displayed for some time and the time for which each element is displayed should be determined by a value in each element.
let array=[{display:"a",time:10},{display:"b",time:15},{display:"c",time:22}]
class App extends React.Component{
state={stateDisplay:"",
stateTime:""
}
componentWillMount(){
var i=0;
let handle=setInterval(()=>{
var element= array[i]
this.setState({
stateDisplay:element.display,
stateTime:element.time,
})
i=i+1;
if(i===array.length){
clearInterval(handle)
}
},10000)
}
render(){
return(
<div> {this.state.stateDisplay} </div>
)}}
i have done something like this but using setinterval the delay can only be set for a constant time,here 10s. I want the first element to display for 10s and then the next element for 15s, third for 22s which is the time value for each element of the array. I know i cant do that using setinterval is there a way to do this using Settimeout?
回答1:
This was almost like a little challenge, heres what i managed to come up with, its in typescript, if you need js, just remove interfaces and type annotations
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable prettier/prettier */
/* eslint-disable no-shadow */
/* eslint-disable no-console */
import React, { FC, useState, useEffect, useCallback } from 'react';
import { View, Button, Text } from 'react-native';
interface Data {
duration: number;
bgColor: string;
}
const dataArr: Data[] = [
{ duration: 3, bgColor: 'tomato' },
{ duration: 6, bgColor: 'skyblue' },
{ duration: 9, bgColor: 'gray' },
];
const Parent = () => {
const [currentIdx, setCurrentIdx] = useState<number>(0);
const [elementData, setElementData] = useState<Data>(dataArr[currentIdx]);
useEffect(() => {
console.log('idx', currentIdx);
if (currentIdx > dataArr.length) return;
setElementData({ ...dataArr[currentIdx] });
}, [currentIdx]);
const pushNext = () => {
setCurrentIdx(currentIdx + 1);
};
const handleRestart = () => {
setCurrentIdx(0);
setElementData({ ...dataArr[0] });
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Timer
data={elementData}
onCountDownComplete={pushNext}
restart={handleRestart}
/>
</View>
);
};
interface Props {
data: Data;
onCountDownComplete: () => void;
restart: () => void;
}
const Timer: FC<Props> = ({ data, onCountDownComplete, restart }) => {
const [seconds, setSeconds] = useState<number>(data.duration);
// update on data change
useEffect(() => {
setSeconds(data.duration);
}, [data]);
const callback = useCallback(() => {
onCountDownComplete();
}, [onCountDownComplete]);
useEffect(() => {
let interval: any = null;
if (seconds > -1) {
interval = setInterval(() => {
if (seconds - 1 === -1) {
callback();
} else {
setSeconds(seconds - 1);
}
}, 1000);
} else {
return;
}
return () => {
clearInterval(interval);
};
}, [seconds, callback]);
return (
<View
style={{ backgroundColor: data.bgColor, padding: 16, borderRadius: 10 }}
>
<Text style={{ marginBottom: 24 }}>{seconds}</Text>
<Button title="restart" onPress={restart} />
</View>
);
};
来源:https://stackoverflow.com/questions/62714668/how-to-display-each-element-of-an-array-with-different-timeout-delay-and-each-de