Search code examples
reactjsreactjs.net

Start a setTimeout in componentDidMount and end it in componentWillUnmount in React


I'm here to ask for your help a little thing (I'm sure it's little) that is driving me crazy. First of all I'm pretty new to React and that's probably why it's hard for me to solve this issue. Basically I've put a slideshow on the site to show a picture every four seconds and it works perfectly, until I unmount the component that holds the slideshow (because the setTimeout didn't stop). I admit, at first I've decided to let it be, because it didn't kill the site, but then I discovered that it messes up with the mobile view so I have to fix it. The problem is: I cannot seem to be able to find a way to use clearTimeout in componentWillUnmount. Can you help me please? This is my component:

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>
        );
}

Solution

  • You can assign your setTimeout to a variable and clear that in componentWillUnmount.

    Better way to handle image slider(Caurousel) using setInterval

    Example

      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);
      }
    

    Live working demo