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