【问题标题】: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-07-03 11:40:21
【问题描述】:

数组的每个元素都应该显示一段时间,每个元素显示的时间应该由每个元素中的值决定。

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>
)}}

我做过类似的事情,但是使用 setinterval 只能将延迟设置为一个恒定的时间,这里是 10 秒。 我希望第一个元素显示 10 秒,然后下一个元素显示 15 秒,第三个元素显示 22 秒,这是数组中每个元素的时间值。 我知道我不能使用 setinterval 做到这一点有没有办法使用 Settimeout 做到这一点?

【问题讨论】:

  • 您应该发布最低限度的可重现示例。访问stackoverflow.com/help/minimal-reproducible-example
  • @TheAlpha93 现在我已经给出了一个例子,请检查它并提供问题的解决方案。谢谢
  • @ArvindShrivastava 我是编码新手。我不懂打字稿所以请帮助我理解 js 中的答案

标签: javascript arrays reactjs react-native settimeout


【解决方案1】:

这几乎就像一个小挑战,这是我设法想出的,它在 typescript 中,如果你需要 js,只需删除接口和类型注释

/* 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>
  );
};

【讨论】:

    猜你喜欢
    • 2017-01-05
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 2012-01-07
    相关资源
    最近更新 更多