How to display each element of an array with different timeout delay and each delay time being a value inside each element in react

妖精的绣舞 提交于 2020-08-20 12:19:10

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!