Как повторить функцию в react

#javascript #node.js #reactjs

#javascript #node.js #reactjs

Вопрос:

Мне нужна повторяющаяся функция в react. У меня есть массив слов и элемент, который я хочу менять каждые 2 секунды на следующий элемент массива и снова и снова. Если массив заканчивается, начните сначала. Я попробовал этот код:

   const words = ['Hi', 'Gutten Tag', 'Hola', 'Bonjour']
  const [word, updateWord] = useState(0) // The word would be accessible at words[word] 

  function handleLoop() {
    if (word === words.length - 1) {
      updateWord(0)
    }
    else {
      updateWord(word   1)
    }
    setTimeout(handleLoop(), 2000)
  }
 

Но react считает, что это вызовет бесконечный цикл.
Ошибка

Как я должен это исправить?

Комментарии:

1. братан, тебе setTimeout(handleLoop, 2000) не нужно этого делать setTimeout(handleLoop(), 2000) . Вы вызываете функцию прямо там, в setTimeout

Ответ №1:

Используйте хук useEffect

Вы можете useEffect запускать перехват каждые 2 секунды, обновляя word и указывая его в списке зависимостей.

 const { useEffect, useState } = React;

// keep words in a separate constants.js file
// if it's a constant and not consumed from an API
const words = ["Hi", "Gutten Tag", "Hola", "Bonjour"];

const App = () => {
  // maintain word as a local state
  const [word, updateWord] = useState(0);

  // hook will be triggerd every time word
  // gets updated after every 2000ms
  useEffect(() => {
    let nextWord;

    // logic stays the same
    if (word === words.length - 1) {
      nextWord = 0;
    } else {
      nextWord = word   1;
    }

    // update the word
    setTimeout(() => updateWord(nextWord), 2000);
  }, [word]);

  return (
    <p>{words[word]}</p>
  );
}

ReactDOM.render(<App />,document.getElementById('react')); 
 <div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> 

Ответ №2:

Происходит переполнение стека

Исправить:

  const words = ['Hi', 'Gutten Tag', 'Hola', 'Bonjour']
 const [word, updateWord] = useState(0) // The word would be accessible at words[word] 

 function handleLoop() {
   if (word === words.length - 1) {
     updateWord(0)
   }
   else {
     updateWord(word   1)
   }
 }

 setInterval(handleLoop, 2000)
 

Комментарии:

1. Эй, попробуйте немного объяснить свой ответ вместо того, чтобы публиковать ответы «только с кодом», это сделает ваш ответ более читабельным и предоставит больше контекста для кода.

Ответ №3:

Я думаю, что setInterval — лучший способ, здесь

 const words = ['Hi', 'Gutten Tag', 'Hola', 'Bonjour']
const [word, updateWord] = useState(0) // The word would be accessible at words[word] 

let handleLoop = function() {
    if (word === words.length) {
      updateWord(0)
    }
    else {
      updateWord(word   1)
    }
    console.log(words[word])
  }

 setInterval(handleLoop, 2000)
 

Комментарии:

1. Это сработало в первые 3 раза, затем начались следующие сбои: i.imgur.com/fH1Nvc5.gif

Ответ №4:

 function countDown(fromNumber) {
    console.log(fromNumber);

    let nextNumber = fromNumber - 1;

    if (nextNumber > 0) {
        countDown(nextNumber);
    }
}
countDown(3);
 
 function countDown(fromNumber) {
    console.log(fromNumber);

    let nextNumber = fromNumber - 1;

    if (nextNumber > 0) {
        countDown(nextNumber);
    }
}
countDown(3); 

Комментарии:

1. Я предлагаю добавить несколько комментариев, которые объяснят ваш ответ.

2. Пожалуйста, добавьте объяснение, чтобы улучшить понимание и предоставить OP дополнительную информацию