如何获取setInterval以在应用延迟之前运行一次回调函数

时间:2019-04-30 11:30:43

标签: javascript reactjs react-hooks

我在useEffect挂钩中运行setInterval来循环一个函数,但是,我希望能够在应用延迟(间隔)之前先运行一次该函数。在应用延迟之前,有什么方法可以在useEffect挂钩中运行一次该函数吗?

我尝试在setInterval函数之前在挂钩内运行一次该函数,但没有得到我希望的结果。在useEffect钩子外部运行函数也是如此。

  const myText = props.text;
  const textTimeout = 100;
  const funTextInterval = textTimeout * myText.length
  const [quickText, setQuickText] = useState([]);

  const setDelay = (i) => {
    setTimeout(() => {
       myFunction();
     , textTimeout * i);
  };

  useEffect(() => {
    setInterval(() => {
      for (let i = 0; i < myText.length + 1; i++) {
        setDelay(i);
      }
    }, funTextInterval);    
  }, []);

我希望forloop在setInterval的延迟开始之前运行一次,但是延迟发生在forloop之前

3 个答案:

答案 0 :(得分:2)

在方法中取出for循环逻辑,并在setInterval之前和setInterval内部调用它

[
    {
        "_id": "5cc695defaa9550f30220e52",
        "participants": [
            {
                "_id": "5cc695defaa9550f30220e54",
                "userEmail": "john@gmail.com"
            },
            {
                "_id": "5cc695defaa9550f30220e53",
                "userEmail": "user2@gmail.com"
            }
        ],
        "chatType": "chat",
        "messages": [],
        "__v": 0
    },
    {
        "_id": "5cc695e3faa9550f30220e55",
        "participants": [
            {
                "_id": "5cc695e3faa9550f30220e57",
                "userEmail": "test@gmail.com"
            },
            {
                "_id": "5cc695e3faa9550f30220e56",
                "userEmail": "user2@gmail.com"
            }
        ],
        "chatType": "chat",
        "messages": [],
        "__v": 0
    },
    {
        "_id": "5cc811597990d5516431de50",
        "participants": [
            {
                "_id": "5cc811597990d5516431de52",
                "userEmail": "test@gmail.com"
            },
            {
                "_id": "5cc811597990d5516431de51",
                "userEmail": "user2@gmail.com"
            }
        ],
        "chatType": "chat",
        "messages": [],
        "__v": 0
    },
    {
        "_id": "5cc8115a7990d5516431de53",
        "participants": [
            {
                "_id": "5cc8115a7990d5516431de55",
                "userEmail": "test@gmail.com"
            },
            {
                "_id": "5cc8115a7990d5516431de54",
                "userEmail": "user2@gmail.com"
            }
        ],
        "chatType": "chat",
        "messages": [],
        "__v": 0
    },
    {
        "_id": "5cc8115a7990d5516431de56",
        "participants": [
            {
                "_id": "5cc8115a7990d5516431de58",
                "userEmail": "test@gmail.com"
            },
            {
                "_id": "5cc8115a7990d5516431de57",
                "userEmail": "user2@gmail.com"
            }
        ],
        "chatType": "chat",
        "messages": [],
        "__v": 0
    }
]

答案 1 :(得分:1)

您可以这样分离逻辑:

  const myText = props.text;
  const textTimeout = 100;
  const funTextInterval = textTimeout * myText.length
  const [quickText, setQuickText] = useState([]);

  function applyTextEffect() {
      for (let i = 0; i < myText.length + 1; i++) {
        setTimeout(myFunction, textTimeout * i);
      }
  }

  useEffect(() => {
    applyTextEffect()  // call it here immediately to get the effect you want.
    setInterval(applyTextEffect, funTextInterval);    
  }, []);

但是请注意,此组件将通过在每次更新时调用文本效果函数来创建不需要的效果。 UseEffect在每次更新中均有效。最好有一个isMounted状态变量,并在其周围实现逻辑以仅应用效果一次。

编辑:存储从setInterval函数返回的间隔id并清除它以返回useEffect也是明智的。否则,当您的组件将被销毁时,您将获得异常

答案 2 :(得分:0)

仅使用for循环编写单独的函数。
在调用useEffect()之前先调用该函数。
从useEffect()-> setInterval()内部,调用新方法。

下面给出未经测试的代码以供说明。

const myText = props.text;
const textTimeout = 100;
const funTextInterval = textTimeout * myText.length
const [quickText, setQuickText] = useState([]);

const setDelay = (i) => {
  setTimeout(() => {
     myFunction();
   , textTimeout * i);
};

runloop(){
  for (let i = 0; i < myText.length + 1; i++) {
    setDelay(i);
  }
}

useEffect(() => {
  setInterval(() => {
    runloop()
  }, funTextInterval);    
}, []);

runloop();