#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 дополнительную информацию