在函数中反应太多重新渲染

时间:2021-02-27 21:55:41

标签: javascript reactjs

我正在根据 ImageGallery 的提示尝试在 ReactJS 中创建幻灯片放映组件]1

但是当我调试我的代码时出现了这个错误:

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
            )
        )
    );
}

我发现这是导致错误的代码,但我不知道错误在哪里。

我对 ReactJS 不是很熟练。

1 个答案:

答案 0 :(得分:1)

这里应该不是调用,而是函数

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

那样

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