возникли проблемы с получением одного элемента из массива каждую секунду в React

#javascript #reactjs

Вопрос:

Я пытаюсь просмотреть некоторые элементы, для этого я привел простой пример для тестирования: [1, 2, 3, 4, 5]

Я также должен написать следующий код:

     useEffect(() => {
        const interval = setInterval(() => {
            const numbers = [1, 2, 3, 4, 5];
            const doubled = numbers.map((number) => number * 2);
            console.log(doubled);
        }, 3000)
    }, []) 
 

это дает мне следующий вывод 1,2,3,4,5 каждые 3 секунды в журнале конкола.
Но чего я хочу добиться, так это: показать 1 -> подождать 3 секунды ->> показать 2 ->>> подождать 3 секунды ->>>> показать 4 и т. Д

Каков наилучший способ получить этот результат ?

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

1. Вам нужно будет где-то вести подсчет индекса. Я также предлагаю использовать useInterval , потому что использование setInterval в эффекте может вызвать неожиданное поведение.

Ответ №1:

Добавьте index состояние и используйте useEffect крючок, чтобы просто обновить индекс. Используйте второй useEffect хук для доступа к numbers массиву и вычисления двойника. Обратите внимание, что второй эффект принимает модуль индекса за длину массива чисел, поэтому индекс всегда находится в диапазоне.

Примечание: Не забудьте очистить интервал, когда компонент размонтируется!

 const numbers = [1, 2, 3, 4, 5];

function App() {
  const [index, setIndex] = React.useState(0);

  React.useEffect(() => {
    const interval = setInterval(() => {
      setIndex((i) => i   1);
    }, 3000);
    return () => clearInterval(interval);
  }, []);

  React.useEffect(() => {
    const doubled = numbers[index % numbers.length] * 2;
    console.log(doubled);
  }, [index]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Edit to see some magic happen!</h2>
    </div>
  );
}

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

Ответ №2:

Это похоже на школьный пример использования генератора. Что-то из следующих строк должно сработать:

 function *test() {
  const numbers = [1,2,3,4,5]
  let idx=0
  while (idx < numbers.length){
    yield numbers[idx]
    idx  
  }
}

let gen = test()
setInterval( () => console.log(gen.next().value), 1000)
 

Вам просто нужно добавить некоторую проверку done значения генератора.

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

1. Хотя мне нравится идея использования функции генератора, я не уверен, насколько хорошо это вписалось бы в компонент React, которому требуется обновление состояния/реквизита для запуска повторного запроса. Хотя начальный рендеринг запустил бы интервал, и обратный вызов мог бы регистрировать каждое полученное значение независимо от жизненного цикла компонента.

2. Ах да, я пропустил ответную часть вопроса. Я не могу ответить на этот вопрос, так как мне не хватает необходимых навыков реагирования.