Запустите setTimeout в componentDidMount и завершите его в componentWillUnmount в React

#reactjs #reactjs.net

Вопрос:

Я здесь, чтобы попросить вас о помощи в одной мелочи (я уверен, что это мелочь), которая сводит меня с ума. Во-первых, я довольно новичок в реагировании, и, вероятно, поэтому мне трудно решить эту проблему. В принципе, я разместил слайд-шоу на сайте, чтобы показывать картинку каждые четыре секунды, и оно отлично работает, пока я не отключу компонент, содержащий слайд-шоу (потому что setTimeout не остановился). Признаюсь, сначала я решил оставить это в покое, потому что это не убило сайт, но потом я обнаружил, что он портит мобильный просмотр, поэтому я должен это исправить. Проблема в том, что я, похоже, не могу найти способ использовать clearTimeout в componentWillUnmount. Вы можете мне помочь, пожалуйста? Это мой компонент:

 class PictureSlider extends React.Component {

componentDidMount() {
    
    var slideIndex = 0;
    showSlides();

    function showSlides() {
        var i;
        var slides = document.getElementsByClassName("mySlides");
        for (i = 0; i < slides.length; i  ) {
            slides[i].style.display = "none";
        }
        slideIndex  ;
        if (slideIndex > slides.length) { slideIndex = 1 }
        slides[slideIndex - 1].style.display = "block";
        setTimeout(showSlides, 4000)
        
    }
}

componentWillUnmount() {
}

render() {
    return (
        <div className="slideshow-container">
            <div className="mySlides fade">
                <img src="/images/photo/image00024.jpeg" style={{ width: '100%' }} />
            </div>

            <div className="mySlides fade">
                <img src="/images/photo/image00005.jpeg" style={{ width: '100%' }} />
            </div>

            <div className="mySlides fade">
                <img src="/images/photo/image00021.jpeg" style={{ width: '100%' }} />
            </div>

            <div className="mySlides fade">
                <img src="/images/photo/image00025.jpeg" style={{ width: '100%' }} />
            </div>

            <div className="mySlides fade">
                <img src="/images/photo/image00014.jpeg" style={{ width: '100%' }} />
            </div>

            <div className="mySlides fade">
                <img src="/images/photo/image00029.jpeg" style={{ width: '100%' }} />
            </div>

            <div className="mySlides fade">
                <img src="/images/photo/image00030.jpeg" style={{ width: '100%' }} />
            </div>

            <div className="mySlides fade">
                <img src="/images/photo/euro1ad.jpg" style={{ width: '100%' }} />
            </div>
        </div>
        );
}
 

Ответ №1:

Вы можете назначить свою setTimeout переменную и очистить ее componentWillUnmount .

Лучший способ обработки слайдера изображений(карусели) с помощью setInterval

Пример

   componentDidMount() {
    var slideIndex = 0;

    this.timer = setInterval(() => {
      var i;
      var slides = document.getElementsByClassName("mySlides");
      for (i = 0; i < slides.length; i  ) {
        slides[i].style.display = "none";
      }
      slideIndex  ;
      if (slideIndex > slides.length) {
        slideIndex = 1;
      }
      slides[slideIndex - 1].style.display = "block";
    }, 4000);
  }

  componentWillUnmount() {
    clearInterval(this.timer);
  }
 

Живая рабочая демонстрация

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

1. Большое вам спасибо, это сработало идеально!

Ответ №2:

Вот как вы можете это сделать.

 class PictureSlider extends React.Component {
  state = {
    timeout: null,
  }

  componentDidMount() {
    var slideIndex = 0
    showSlides()

    function showSlides() {
      var i
      var slides = document.getElementsByClassName('mySlides')
      for (i = 0; i < slides.length; i  ) {
        slides[i].style.display = 'none'
      }
      slideIndex  
      if (slideIndex > slides.length) {
        slideIndex = 1
      }
      slides[slideIndex - 1].style.display = 'block'
      // assign to state variable
      this.setState({ timeout: setTimeout(showSlides, 4000) })

    }
  }

  componentWillUnmount() {
    // clear the timeout assigned to state
    clearTimeout(this.state.timeout)
  }

  render() {
    return (
      <div className='slideshow-container'>
        <div className='mySlides fade'>
          <img src='/images/photo/image00024.jpeg' style={{ width: '100%' }} />
        </div>

        <div className='mySlides fade'>
          <img src='/images/photo/image00005.jpeg' style={{ width: '100%' }} />
        </div>

        <div className='mySlides fade'>
          <img src='/images/photo/image00021.jpeg' style={{ width: '100%' }} />
        </div>

        <div className='mySlides fade'>
          <img src='/images/photo/image00025.jpeg' style={{ width: '100%' }} />
        </div>

        <div className='mySlides fade'>
          <img src='/images/photo/image00014.jpeg' style={{ width: '100%' }} />
        </div>

        <div className='mySlides fade'>
          <img src='/images/photo/image00029.jpeg' style={{ width: '100%' }} />
        </div>

        <div className='mySlides fade'>
          <img src='/images/photo/image00030.jpeg' style={{ width: '100%' }} />
        </div>

        <div className='mySlides fade'>
          <img src='/images/photo/euro1ad.jpg' style={{ width: '100%' }} />
        </div>
      </div>
    )
  }
}
 

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

1. Разве состояние не должно быть объявлено в конструкторе? Это решение не работает :/

2. Прошу прощения, произошла ошибка. Я отредактировал. Пожалуйста, проверьте еще раз.