building automated Image slideshow with styled component

Viewed 35

I am trying to build my am image slideshow, but because I am using styled component, I encountered some difficulties.

since i can't use use getElementByID method i decide to use the useRef method but still I am yet to succeed.

i have the three different approaches

 function Slider({}) {
     const refImg = useRef(null);
     let slides = refImg.current;
     slides.style.display = "block";
      let slideIndex = 0;
       function showSlides() {
     let i;
     for (i = 0; i < slides.length; i++) { 
         slides[i].style.display = "none";
    }
     slideIndex++;
     if (slideIndex > slides.length) { slideIndex = 1}
     slides[slideIndex-1].style.display = "grid";
     setTimeout(showSlides, 2000);
    }
       showSlides();

     return (
       <Wrap>
         <ContentLayout>
            <Contents>
               <ImageHolder refImg={refImg}>
                       <Image alt = '' src = {img1} />
                </ImageHolder>
                 <ImageHolder refImg={refImg}>
                       <Image alt = '' src = {img2} />
                </ImageHolder>
                 <ImageHolder refImg={refImg}>
                       <Image alt = '' src = {img3} />
                </ImageHolder>
               </Contents>
            </ContentLayout>
        </Wrap
      )
     }

     export default Slider  

my first approach ERROR (uncaught type error cannot read property of null (reading 'style'))

styled component css

const Contents = styled.section`
  bottom: 0px;
  display: block;
  opacity: 1;
  left: 0px;
  right: 0px;
  top: 0;
  bottom: 0;
  inset-block: 0px;
  inset-inline: 0px;
  height: 100%;
  overflow: hidden;
 transition: opacity 1.5s ease 0s;
`

const ImageHolder = styled.div.attrs(({ref}) => ({
ref: ref,
}))`
height: 100%;
position: absolute;
top: 50%;
width: 100%;
overflow: visible;
transform: translateY(-50%) scale(1);
@media (min-width: 900px) {
    top: 50%;
    transform: translateY(-50%) scale(1);
    block-size: 100%;
    position: absolute;
}
`

my second approach ERROR (uncaught type error cannot read property of null (reading 'forEach'))

    let currentSlide = 0;
    const init = (n) => {
     refImg.current.forEach((slide) => {
        refImg.current.style.display = "display"
     });
     refImg.current[n].style.display = "block"
  }

  function next() {
    currentSlide >= refImg.length -1 ? currentSlide = 0 : currentSlide++
     init(currentSlide)
 }

  setInterval(() => {
     next()
   }, 500)

my last approach i modify the code a litle

      const photos = [
    { im: Image1},
    { im: Image2},
    { im: Image3},
    { im: Image4},
];

const [{pics, activeIndex}, setState] = useState({
    pics: photos,
    activeIndex: 0,
});
 const next = (newIndex) => {
        if (newIndex >= -1) {
            setState((s) => ({
                ...s, activeIndex: pics.length -1
            }));
            return;
        }
        if (newIndex === pics.length) {
            setState((s) => ({
                ...s, activeIndex: 0
            }));
            return;
        }
        setState((s) => ({
            ...s, activeIndex: newIndex
        }))
    }
     setInterval(() => {
        next(activeIndex-1)
     }, 200)

     return (
       <Wrap>
         <ContentLayout>
            <Contents>
               <ImageHolder refImg={refImg}>
                       <Image alt = '' src = {pics[activeIndex].im} />
                </ImageHolder>
               </Contents>
            </ContentLayout>
        </Wrap
      )

NO error but the slide only moves once from image1 to image2 and stop. pls help

0 Answers
Related