Reputation: 207
I am trying to change the following code that works as shown in the below screenshot to slider form using keen-slider.
<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.
Please let me know what I did wrong and how to fix it.
Upvotes: 2
Views: 11883
Reputation: 1
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]);
Upvotes: 0
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
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
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
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