How to clear setTimeout when the page is changed in reactjs – nextjs

Advertisements

I created a slideshow in the Nextjs project, But I have a bug. When the user clicks on a link and the page has changed I get an Unhandled Runtime Error and I know it because of the setTimeout function it calls a function and tries to style an element that does not exist on the new page.
How can I clear the setTimeout function after the user click the links?

Error screenshot:

My component code:

import { useEffect, useState } from "react";
import SlideContent from "./slide-content";
import SlideDots from "./slide-dots";
import SlideItem from "./slide-item";

const Slide = (props) => {
  const { slides } = props;
  const [slideLength, setSlideLength] = useState(slides ? slides.length : 0);
  const [slideCounter, setSlideCounter] = useState(1);

  const handleSlideShow = () => {
    if (slideCounter < slideLength) {
      document.querySelector(
        `.slide-content:nth-of-type(${slideCounter})`
      ).style.left = "100%";
      const setSlide = slideCounter + 1;
      setSlideCounter(setSlide);

      setTimeout(() => {
        document.querySelector(
          `.slide-content:nth-of-type(${setSlide})`
        ).style.left = 0;
      }, 250);
    } else {
      document.querySelector(
        `.slide-content:nth-of-type(${slideCounter})`
      ).style.left = "100%";
      setSlideCounter(1);
      setTimeout(() => {
        document.querySelector(`.slide-content:nth-of-type(1)`).style.left = 0;
      }, 250);
    }
  };

  useEffect(() => {
    if (slideLength > 0) {
      setTimeout(() => {
        handleSlideShow();
      }, 5000);
    }
  }, [slideCounter, setSlideCounter]);

  return (
    <>
      <div className="slide-button-arrow slide-next">
        <span className="carousel-control-prev-icon"></span>
      </div>
      <div className="slide">
        {slides.map((slide) => (
          <SlideContent key={`slide-${slide.id}`}>
            <SlideItem img={slide.img} title={slide.title} />
          </SlideContent>
        ))}
        <SlideDots activeDot={slideCounter} totalDots={slides} />
      </div>
      <div className="slide-button-arrow slide-prev">
        <span className="carousel-control-next-icon"></span>
      </div>
    </>
  );
};

export default Slide;

I use my slideshow component inside the home page file.

>Solution :

useEffect(() => {

    let timer;
    if (slideLength > 0) {
      timer=setTimeout(() => {
        handleSlideShow();
      }, 5000);
    }

    return () => {
      clearTimeout(timer);
    };
  }, [slideCounter, setSlideCounter]);

Leave a Reply Cancel reply