css – React does not render all images in a list

I have a carousel component that reproduces its children and shows one child at a time (each child is a picture). This component consists of “viewport-div” and “wrapper-div”. Wrapper-div contains all images. To change active image I change css-transform of a wrapper-div. The carousel component takes the ‘ActiveImage’ prop that defines which child is displayed. If I e.g. changes ActiveImage plugin from x to y, wrapper-div slides to image y, and I should be able to see each image during this animation. But when the difference between new and Former The ActiveImage value is more than 6, let’s say from 0 to 10, I can only see 6 images, images 7,8 and 9 are invisible, and when the animation ends, image 10 is displayed, but this problem only occurs if there is no something happens on the screen ie. if i click anywhere on the screen, press random keys or scroller everything works fine. All images are minified (~ 100kb) and here’s how I import them:

export const images = new Array(30).fill(null)

.map((image, number)=>{

    const name = number > 8 ? `${number+1}-min` : `0${number+1}-min`

    return {
        src: process.env.PUBLIC_URL + `/images/min/${name}.jpg`,
        alt:name
    }

})

I do not think this is component logic related, but only if here is the code:

import React, {FC, useEffect, useRef, useState} from 'react';
import styles from './Carousel.module.scss';


type CarouselProps = {
    activeSlideNumber?: number
}


const Carousel: FC<CarouselProps> = ({children, activeSlideNumber}) => {

const [width, setWidth] = useState(0);
const [allowStartDrag, setAllowStartDrag] = useState(true);
const [isDragging, setIsDragging] = useState(false);     // enables carousel move
const [xCoord, setXCoord] = useState(0);
const [currentShift, setCurrentShift] = useState(0);
const [savedShift, setSavedShift] = useState(0);
const [activeSlide, setActiveSlide] = useState(0);

const itemsCount = React.Children.toArray(children).length;

const wrapperRef = useRef<null | HTMLDivElement>(null);  // carousel viewport
const lineRef = useRef<null | HTMLDivElement>(null);     // carousel draggable line

let timeout = null as null | NodeJS.Timeout;

useEffect(()=>{
    if (activeSlideNumber!==undefined) setActiveSlide(activeSlideNumber)
},[activeSlideNumber])

useEffect(() => {

    if (lineRef.current) {

        setAllowStartDrag(false);

        if (timeout) {
            clearTimeout(timeout)
        }

        const slidesPerSweep = Math.abs((currentShift - activeSlide * width) / width);
        const slowDownCoeff = 0.25 * slidesPerSweep;
        setCurrentShift(activeSlide * width);
        setSavedShift(activeSlide*width);

        lineRef.current.style.transition = `transform ${slowDownCoeff}s ease 0s`;
        lineRef.current.style.transform = `translateX(${-activeSlide * width}px)`;

        timeout = setTimeout(() => {

            if (lineRef.current) {
                lineRef.current.style.transition = ``;
            }
            setAllowStartDrag(true);
        }, slowDownCoeff * 1000)
    }

}, [activeSlide])

useEffect(() => {

    if (wrapperRef.current) setWidth(wrapperRef.current.clientWidth)


}, [width])


const onDrag = (e: React.PointerEvent<HTMLDivElement>) => {
    if (!isDragging) return

    const shift = xCoord - e.pageX;

    setCurrentShift(() => {

        if (shift + savedShift < 0) return 0

        if (shift + savedShift > (itemsCount - 1) * width) return (itemsCount - 1) * width

        return shift + savedShift
    });

    e.currentTarget.style.transform = `translate(${-currentShift}px)`;

}

const onSwipeStart = (e: React.PointerEvent) => {
    if (!allowStartDrag) return
    setXCoord(e.pageX);
    setIsDragging(true);
}

const completeSwipe = () => {

        if (currentShift > savedShift ) {
            setActiveSlide(p => p + 1);
        } else if (currentShift < savedShift) {
            setActiveSlide(p => p - 1);
        }

}


const onSwipeEnd = (e: React.PointerEvent) => {
    completeSwipe();
    setIsDragging(false);
}

const onMouseLeave = (e: React.PointerEvent) => {
    completeSwipe();
    setIsDragging(false)
}

return (
    <div className={styles.wrapper} style={{
        width: `${width}px`
    }}>
        <div className={styles.item_line}
             ref={lineRef}
             onPointerDown={onSwipeStart}
             onPointerUp={onSwipeEnd}
             onPointerMove={onDrag}
             onPointerLeave={onMouseLeave}
        >

            {React.Children.toArray(children).map((child, i) => {

                return (
                    <div key={i} ref={i === 0 ? wrapperRef : undefined} className={styles.item}>
                        {child}
                    </div>
                )
            })}
        </div>
        <div className={styles.arrow_left}>
            <button onClick={()=>setActiveSlide(p=> p === 0 ? p : p - 1)}>previous</button>
        </div>
        <div className={styles.arrow_right}>
            <button onClick={()=>setActiveSlide(p=> p === itemsCount - 1 ? p : p + 1)}>next</button>
        </div>
    </div>
);
};

export default Carousel;

The only somewhat related thing I was able to find is React Native rendering error, but I’m not familiar with ReactNative, so I hope you can help me.

Leave a Comment