javascriptreactjsslick.jsreact-slick

Accessing slide elements of react-slick slideshow


I'm adding a slideshow using react-slick and implementing my own lazy-loading routine so that I can pre-load images a slide ahead (eventually 2 ahead). In order to do this, I need to access the DOM element containing the list of slides wrapped by Slick. Once I have that element, I should easily be able to use querySelector() to target a slide to load its images.

However, I'm having trouble using the slider ref I've created. It's returning a reference to the Slick object, which is not a DOM element, and using querySelector() on slider.current gives the error:

Uncaught TypeError: slider.current.querySelector is not a function

Any thoughts as to how to reference the Slick DOM element?

    export default function Carousel({ children, ...slickProps }) {
        const slider = useRef();
    
        const slickDefaults = {
            dots: true,
            infinite: false,
            slidesToScroll: 1,
            slidesToShow: 1,
            speed: 200,
            arrows: true
        };
    
        const onNext = () => {
            slider.current.slickNext();
        };
        const onPrev = () => {
            slider.current.slickPrev();
        };
    
        return (
            <Slider
                {...slickDefaults}
                {...slickProps}
                ref={slider}
                className="carousel"
                beforeChange={(_currentSlide, nextSlide) => {
                    if (slider.current) {

                        // The error occurs here
                        const slideElement = slider.current.querySelector(`[data-index="${nextSlide}"]`);

                        if (slideElement) {
                            const images = slideElement.getElementsByTagName('IMG');
                            for (let i = 0; i < images.length; i++) {
                                const image = images[i];
                                const lazySrc = image.getAttribute('data-lazy');
                                if (lazySrc) {
                                    image.setAttribute('src', lazySrc)
                                    image.removeAttribute('data-lazy');
                                }
                            }
                        }
                    }
                }}
                prevArrow={
                    <CarouselButton
                        direction="left"
                        clickEvent={onPrev}
                    />
                }
                nextArrow={
                    <CarouselButton
                        direction="right"
                        clickEvent={onNext}
                    />
                }
            >
                {children}
            </Slider>
        );
    }

Solution

  • It turns out that I just had to dig a little deeper into the object pointed to by the ref. In most cases, ref.current will suffice, but here the slideshow DOM element can be found at: ref.current.innerSlider.list, which references the element div.slick-list.

    The error can be resolved by replacing the line with:

    const slideElement = slider.current.innerSlider.list.querySelector(`[data-index="${slideIndex}"]`);