react-slick: Problem in rendering Slider with dynamic children

If I render Slider as below:

<Slider {...settings}>
    {slides.map((slide) => (
        <div key={slide.index}>{slide.index}</div>
    ))}
</Slider>

nextProps.children.length in componentWillReceiveProps of class InnerSlider will always returns 1 which breaks the sliding logic.

Does Slider not expect dynamic children?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 18
  • Comments: 44 (6 by maintainers)

Most upvoted comments

Hey chochihim, it looks like you’re not returning your <div> inside map()

try:

<Slider {...settings}>
    {slides.map((slide) => (
        return (<div key={slide.index}>{slide.index}</div>);
    ))}
</Slider>

@hackhat I had exactly the same issue and fixed by adding data-index attribute to my slide elements, more or less like this:

<Slider {...settings}>
  {slides.map((slide, index) => (
    <div data-index={index} key={index}>{index}</div>
  ))}
</Slider>

I’ve just started adding this library to my project, so I’m not sure if it won’t cause some other issues later on.

@samplefrequency Agreed. I will try to fix it soon

Solved it. Writing it here for ppl who run into this in the future :

Had help from a colleague and he pointed out that I needed only to take out the div from this line

<Slider{...settings}>
   <div>{this.renderGallery(listing)}</div>
</Slider> : null }

Apparently, if I leave it there, the Slider will pick up that one big <div>and count that, which means it will not render according to the other many <div></div> s within it.

Side note: I didn’t even need the data-index in the .map, though the ternary is still needed for fallback purposes.

Code now looks like this:

 {this.props.listingGalleryImages.loaded === true &&
   <div className="container">
       {this.renderGallery(listing).length > 0 ? 
        <Slider {...settings}>{this.renderGallery(listing) </Slider> : null }
   </div>
 }

@kevin700brands You might have missed importing the CSS files:

just try adding the two lines of code in ur app.js file:

import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";

As a quick workaround, you can mount slider only if you have slides.

{slides.length > 0 ? <Slider>{slides}</Slider> : null }

+1 same here. basically this line fails return elem.getBoundingClientRect().height || elem.offsetHeight; because elem is null. It comes from slickList.querySelector('[data-index="0"]').

version 15.3.2 Cannot read property ‘getBoundingClientRect’ of null

@walston no, mine is valid shorthand

In my jsfiddle example, the initial rendering is fine but not after clicking ‘Add slide’.

When will this fix be added to NPM?

@ypyang237 Just as a side note, instead of the ternary

this.renderGallery(listing).length > 0 ? 
        <Slider {...settings}>{this.renderGallery(listing) </Slider> : null

You could actually use && to make it shorter:

( this.renderGallery(listing).length > 0 ) && <Slider {...settings}>{this.renderGallery(listing) </Slider>

@andricicezar Still won’t fix the issue if the array starts off empty and is later populated via AJAX or from a Redux store.

@szimek That’s the same thing I did, but something doesn’t feel right about it.