WStar
WStar

Reputation: 207

keen-slider does not work on next.js well

I am trying to change the following code that works as shown in the below screenshot to slider form using keen-slider.

enter image description here

        <div className="card-con mt-6">
          {!loadingImages &&
            nftDataArr.map((ele, index) => {
              return (
                <div className="lg:w-3/12 md:w-3/12 w-full"
                  key={index}>
                  <div className="card">
                    <div className="card__cover cursor-pointer">                      
                      <Image
                        src = {ele.image}
                        placeholder="/img/cover/cover5.jpg"
                        className="card__image"
                        width="auto"
                        height="300"
                        />
                    </div>
                  </div>
                </div>
              )
            }
          )};
        </div>

So I changed the code following:

      <div ref={sliderRef} className="keen-slider">            
        {!loadingImages &&
          nftDataArr.map((ele, index) => {
            return (
              <div className="keen-slider__slide">
                <div className="w-full"
                  key={index}>
                  <div className="card">
                    <div className="card__cover cursor-pointer">                      
                      <Image
                        src = {ele.image}
                        placeholder="/img/cover/cover5.jpg"
                        className="card__image"
                        width="auto"
                        height="300"
                        />
                    </div>
                  </div>
                </div>
              </div>
            )
          }
        )};
      </div>

But keen-slider does not work, cards show like the below screenshot. enter image description here

Please let me know what I did wrong and how to fix it.

Upvotes: 2

Views: 11883

Answers (5)

Himanshu Andel
Himanshu Andel

Reputation: 1


I have resolved this issue by updating slider as follow:

const [loading, setLoading] = useState(true);

const [sliderRef, slider] = useKeenSlider({
    loop: true,
    mode: "free-snap",
    slides: { perView: 5 },
    drag: true,
},
)

useEffect(() => {
    setLoading(false);
}, [])

useEffect(() => {
    if (!loading && slider.current) {
        slider.current.update();
    }
}, [loading, slider]);

This approach worked for me... Thanks!

Upvotes: 0

Andrew
Andrew

Reputation: 330

You can update the slider this way:

const [ref, internalSlider] = useKeenSlider({...})
useEffect(() => {
   internalSlider?.current?.update();
}, [elements]);

That was the solution for me.

Upvotes: 1

Johnny Kontrolletti
Johnny Kontrolletti

Reputation: 899

Keen Slider needs the slides to calculate bounds on initialization, any slides added after creation won't be taken into account and slider.update() would have to be called. But since you only have on state which says whether or not the images are rendered, you could just wrap the slider as its whole within your condition:

{!loadingImages && (
   <div ref={sliderRef} className="keen-slider">
      ...
   </div>      
)} 

Or as mentioned before call slider.update() when the images are ready. To avoid flickering you could add visibility: hidden correspondingly.

Upvotes: 3

MMilanov
MMilanov

Reputation: 164

I got the same problem. I managed to fix it by just making the options object for the useKeenSlider() as a empty state object. When I get my items through useEffect() I then set the object with the properties I need. It seems that triggers the ref to update and so updates the slide.

const [options,setOptions] = useState({});
const [sliderRef, slider] = useKeenSlider(options);
const [slides, setSlides] = React.useState([]);


useEffect(()=>{
var data = getDataValues();
setSlides(data);
setOptions({
    slidesPerView: 1,
    mode: "free-snap",
    centered: true,
    loop: false,
    initial: 0,
    slideChanged(s) {
      setCurrentSlide(s.details().relativeSlide);
    },
  });
})

Upvotes: 3

Mnai
Mnai

Reputation: 507

The problem I had with the keen-slider is that my API call would load the images in after the slider has been rendered, keen-slider didn't like that. How I solved this was to run my GQL call in a parent component then once finished loading pass the results to a slider child component where keen-slider is held. In addition to that while its loading I just show a loading icon.

Upvotes: 0

Related Questions