简体   繁体   中英

React too many re-renders in function

I'm trying to create a slide show component in ReactJS taking a cue from ImageGallery] 1

But when I debug my code I got this error:

ShowSlideSpring.js:

    export default function ShowSlideSpring(props) {

    const [currentIndex, setCurrentIndex] = useState(props.startIndex);
    const imageGallerySlideWrapper = useRef();
    let imageGallery = useRef();
    let resizeObserver = useRef();
    const thumbnailsWrapper = useRef();
    const thumbnailsRef = useRef();

    const [isFullscreen, setIsFullscreen] = useState(false);
    const [modalFullscreen, setModalFullscreen] = useState(false);
    const [isTransitioning, setIsTransitioning] = useState(false);
    const [currentSlideOffset, setCurrentSlideOffset] = useState(0);
    const [slideStyle, setSlideStyle] = useState();
    const [previousIndex, setPreviousIndex] = useState();
    const [thumbsTranslate, setThumbsTranslate] = useState();
    const [gallerySlideWrapperHeight, setGallerySlideWrapperHeight] = useState();
    const [isPlaying, setIsPlaying] = useState(false);

    let lazyLoaded;
    let loadedImages = {};
    let playPauseIntervalId;
    let direction;
    let transitionTimer;
    let thumbnailMouseOverTimer;

    if(props.lazyLoad)
        lazyLoaded = [];

    useEffect(() => {
        initResizeObserver(imageGallerySlideWrapper);
        addScreenChangeEvent();
    });

    function canSlide() {
        return props.items.length >= 2;
    }

    function canSlideLeft() {
        return props.infinite || currentIndex > 0;
    }

    function canSlideRight() {
        return props.infinite || (props.items.length - 1);
    }

    function addScreenChangeEvent() {
        document.addEventListener("fullscreenchange", handleScreenChange);
    }

    function initResizeObserver(element) {
        resizeObserver = new ResizeObserver(debounce((entries) => {
            if (!entries) return;
            entries.forEach(() => {
                /*handleResize();*/
            });
        }, 300));
        resizeObserver.observe(element.current);
    }

    function handleScreenChange() {
        //handles screen change events that the browser triggers e.g. esc key
        const fullScreenElement = document.fullscreenElement
        // check if screenchange element is the gallery
        const isFullscreenC = imageGallery.current === fullScreenElement;
        if (props.onScreenChange) props.onScreenChange(isFullscreenC);
        if (props.useBrowserFullscreen) setIsFullscreen(isFullscreenC);
    }

    function twoSlidesFakeSwipe(event, nextIndex) {
        /*When there are only 2 slides fake a tiny swipe to get the slides on the correct side for transitioning */
        setCurrentSlideOffset(currentSlideOffset + 0.001); // this will reset once index changes
        setSlideStyle({transition: 'none'}); // move the slide over instantly
        // add 25ms timeout to avoid delay in moving slides over
        window.setTimeout(() => slideToIndex(nextIndex, event), 25);
    }

    function slidePrevious(event) {
        const nextIndex = currentIndex - 1;

        if (isTransitioning) return;

        if (props.items.length === 2)
            twoSlidesFakeSwipe(event,nextIndex);
        else
            slideToIndex(nextIndex, event);

    }

    function slideNext(event) {
        const nextIndex = currentIndex + 1;

        if (isTransitioning) return;

        if (props.items.length === 2)
            twoSlidesFakeSwipe(event,nextIndex);
        else
            slideToIndex(nextIndex, event);
    }

    function slideToIndex(index, event) {
        if (!isTransitioning) {
            if (event) {
                if (playPauseIntervalId) {
                    // user triggered event while ImageGallery is playing, reset interval
                    pause(false);
                    play(false);
                }
            }

            const slideCount = props.items.length - 1;
            let nextIndex = index;
            if (index < 0)
                nextIndex = slideCount;
            else if (index > slideCount)
                nextIndex = 0;


            if (props.onBeforeSlide && nextIndex !== currentIndex)
                props.onBeforeSlide(nextIndex);

            setPreviousIndex(currentIndex);
            setCurrentIndex(nextIndex);
            setIsTransitioning(nextIndex !== currentIndex);
            setCurrentSlideOffset(0);
            setSlideStyle({transition: `all ${props.slideDuration}ms ease-out`});
            onSliding();
        }
    }

    function play(shouldCallOnPlay = true) {
         if (!playPauseIntervalId) {
             setIsPlaying(true);
             playPauseIntervalId = window.setInterval(pauseOrPlay, Math.max(props.slideInterval, props.slideDuration));
             if (props.onPlay && shouldCallOnPlay)
                 props.onPlay(currentIndex);
         }
     }


     function pause(shouldCallOnPause = true) {
         if (playPauseIntervalId) {
             window.clearInterval(playPauseIntervalId);
             playPauseIntervalId = null;
             setIsPlaying(false);
             if (props.onPause && shouldCallOnPause)
                 props.onPause(currentIndex);
         }
     }

     function pauseOrPlay() {
         if (!props.infinite && !canSlideRight())
             pause();
         else
             slideToIndex(currentIndex + 1);
     }

     function onSliding() {
         transitionTimer = window.setTimeout(() => {
             if (isTransitioning) {
                 setIsTransitioning(!isTransitioning);
                 if (props.onSlide) props.onSlide(currentIndex);
             }
         }, props.slideDuration + 50);
     }

     function getThumbnailStyle() {
            let translate;
        const verticalTranslateValue = thumbsTranslate;

        if (isThumbnailVertical()) {
            translate = `translate(0, ${thumbsTranslate}px)`;
            if (props.useTranslate3D) translate = `translate3d(0, ${thumbsTranslate}px, 0)`;
        } else {
            translate = `translate(${verticalTranslateValue}px, 0)`;
            if (props.useTranslate3D) translate = `translate3d(${verticalTranslateValue}px, 0, 0)`;
        }
        return {
            WebkitTransform: translate,
            MozTransform: translate,
            msTransform: translate,
            OTransform: translate,
            transform: translate,
        };
    }

    function isThumbnailVertical() {
        return props.thumbnailPosition === 'left' || props.thumbnailPosition === 'right';
    }

    function getThumbnailBarHeight() {
        if (isThumbnailVertical()) return {height: gallerySlideWrapperHeight};
        return {};
    }

    const slideWrapperClass = clsx(
        'image-gallery-slide-wrapper',
        props.thumbnailPosition
    );

    const thumbnailWrapperClass = clsx(
        'image-gallery-thumbnails-wrapper',
        props.thumbnailPosition
    );

    const slideWrapper = React.createElement(
        'div',
        { ref: imageGallerySlideWrapper/*, className: slideWrapperClass */},
        props.renderCustomControls && props.renderCustomControls(),
        canSlide() ? React.createElement(
            React.Fragment,
            null,
            props.showNav && React.createElement(
            React.Fragment,
            null,
            props.renderLeftNav(slideNext(), !canSlideLeft()),
            props.renderRightNav(slidePrevious(), !canSlideRight())
            ),
            React.createElement(
                'div',
                { className: 'image-gallery-slides' },
                /*slides*/
            )
        ) : React.createElement(
            'div',
            { className: 'image-gallery-slides' },
            /*slides*/
        ),
    );

    const thumbnailStyle = getThumbnailStyle();
    const igContentClass = clsx('image-gallery-content', props.thumbnailPosition, { fullscreen: isFullscreen });
    const igClass = clsx('image-gallery', props.additionalClass, {'fullscreen-modal': modalFullscreen});

    return (
        React.createElement(
            'div',
            {
                ref: imageGallery,
                className: igClass,
                'aria-live': 'polite'
            },
            React.createElement(
                'div',
                { className: igContentClass },
                (props.thumbnailPosition === 'bottom' || 
                 props.thumbnailPosition === 'right') && slideWrapper,
                props.showThumbnails && React.createElement(
                'div',
                {
                    className: thumbnailWrapperClass,
                    style: getThumbnailBarHeight()
                },
                React.createElement(
                    'div',
                    {
                        className: 'image-gallery-thumbnails',
                        ref: thumbnailsWrapper
                    },
                    React.createElement(
                        'div',
                        {
                            ref: thumbnailsRef,
                            className: 'image-gallery-thumbnails-container',
                            style: thumbnailStyle,
                            'aria-label': 'Thumbnail Navigation'
                        },
                        /*thumbnails*/
                    )
                )
                ),
                (props.thumbnailPosition === 'top' || 
                 props.thumbnailPosition === 'left') && slideWrapper
            )
        )
    );
}

I figured out this is the code that causes the error, but I can't figure out where is the error.

I am not very expert with ReactJS.

Here should be not calls, but funcs

            props.renderLeftNav(slideNext(), !canSlideLeft()),
            props.renderRightNav(slidePrevious(), !canSlideRight())

like that

            props.renderLeftNav(slideNext, !canSlideLeft()),
            props.renderRightNav(slidePrevious, !canSlideRight())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM