Реагируйте на изменение текста элемента, проходя по массиву

#javascript #reactjs #iteration #setinterval

Вопрос:

У меня есть массив текстовых элементов, который выглядит следующим образом

 const sentences  = ['sentence one', 'sentence two', 'sentence three', 'sentence four']
 

Я пытаюсь сделать так, чтобы текст элементов проходил по каждому предложению, отображая каждое в течение пяти секунд, с эффектом ввода наружу, затем эффектом обратного пространства, затем он печатает следующее предложение и зацикливается.

Код, который у меня есть, наберет первое предложение, пробел, наберет второе предложение, а затем снова и снова наберет второе предложение… Есть идеи, что я делаю не так?

Это код, который у меня есть

   const sentences = ['sentence one', 'sentence two', 'sentence three', 'sentence four']
  const [sentence, setSentence] = useState(sentences[0])
  let index = 0
  if(index < 3) {
    setInterval(() => {
      index  
      setSentence(sentences[index])
    }, 5000)
  }
 

Ответ №1:

Каждый раз, когда ваш компонент монтируется, ваша index переменная снова устанавливается в 0. index переменная должна храниться в состоянии:

 const [index, setIndex] = useState(0)
 

Вам нужно установить интервал внутри useEffect , чтобы предотвратить бесконечный повторный монтаж. Затем в вашем useEffect :

 useEffect(() => {
  const interval = setInterval(() => {
      setIndex(index   1)
    }, 5000)

  return (() => clearInterval(interval)) //This is a cleanup function
})
 

Наконец, вы можете представить свое предложение так, как будто sentences[index] вам не нужна sentence переменная состояния. Вы можете взглянуть на кодовое поле, которое я создал для этого вопроса

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

1. У меня это работает, спасибо вам за помощь. Не могли бы вы объяснить, что делает функция очистки?

2. Рад, что это помогло, пожалуйста, примите ответ, если он ответил на ваш вопрос 🙂 Конечно, функция очистки в основном прерывает текущую функцию, когда ваш компонент отключается. Есть гораздо лучшие ресурсы, чем я, чтобы объяснить это. Ознакомьтесь с документацией или этим полезным учебником (где я научился) видео на YouTube

3. Я вроде как просто попробовал это с функцией очистки и без нее и понял, что иногда после нескольких итераций текст будет отображать более одного элемента из массива, но мигать между ними. После добавления функции очистки этого больше не происходит. Спасибо за ссылки, я посмотрю

4. Я бы не ожидал такого поведения. Возможно, это происходит, когда ваш компонент размонтируется и снова монтируется, когда индекс обновляется. Поскольку setInterval является асинхронным, может произойти такое неожиданное поведение. Хотя просто догадываюсь

5. Есть какие-нибудь советы по прекращению этого неожиданного поведения?

Ответ №2:

это было бы то, что вам нужно, я просто отредактировал вышеуказанный код и поле https://codesandbox.io/s/heuristic-goodall-ypntd

 import "./styles.css";
import { useState, useEffect } from "react";

const loopArr = [
  "sentence1",
  "sentence2",
  "sentence3",
  "sentence4",
  "sentence5",
  "sentence5 sentence5"
];

export default function App() {
  const [index, setIndex] = useState(0);

  useEffect(() => {
    const intervalDelayMilliseconds = loopArr[index].length * 500;
    const interval = setInterval(() => {
      setIndex((prevIndex) => {
        // reset index if current index is greater than array size
        return prevIndex   1 < loopArr.length ? prevIndex   1 : 0;
      });
    }, intervalDelayMilliseconds);

    return () => clearInterval(interval);
  });

  return (
    <div className="App">
      <div class="typewriter">
        <h1 key={loopArr[index]}>{loopArr[index]}</h1>
      </div>
    </div>
  );
}
 

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

1. Привет, я попытался попробовать это таким образом, но все закончилось тем, что он снова и снова повторял первое предложение

2. можете ли вы поделиться кодом? и посмотрите результаты вышеупомянутой песочницы здесь ypntd.csb.app