Как заставить setInterval запускать функцию обратного вызова один раз перед применением задержки - PullRequest
2 голосов
/ 30 апреля 2019

Я запускаю setInterval в хуке useEffect для зацикливания функции, однако я хочу иметь возможность запустить эту функцию один раз перед применением задержки (интервала). Есть ли способ, как я могу запустить функцию один раз в хуке 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 ]

2 голосов
/ 30 апреля 2019

Извлекает логику цикла for в методе и вызывает его перед setInterval и внутри setInterval

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

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

  useEffect(() => {
    const loop = () => {
      for (let i = 0; i < myText.length + 1; i++) {
        setDelay(i);
      }
    }
    loop();
    setInterval(() => {
      loop();
    }, funTextInterval);    
  }, []);
1 голос
/ 30 апреля 2019

Вы можете разделить свою логику следующим образом:

  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 работает в каждом обновлении. Лучше иметь переменную состояния isMounting и реализовать логику вокруг нее, чтобы применить эффект только один раз.

РЕДАКТИРОВАТЬ: также целесообразно сохранить идентификатор интервала, возвращенный функцией setInterval, и очистить его в ответ на useEffect. В противном случае, когда ваш компонент будет уничтожен, вы получите исключения

0 голосов
/ 30 апреля 2019

написать отдельную функцию только с циклом 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();
...