React-id-swiper: slidesPerView ignored on first display

Created on 11 Jul 2018  路  11Comments  路  Source: kidjp85/react-id-swiper

The slidesPerView param seems to be ignored on the initial display of the swiper. If I start resizing the page then it starts displaying correctly, while on the first load it just shows all the slides in a very tiny swiper box.

These are my current swiper params. As you can see I also tried both setting rebuildOnUpdate and shouldSwiperUpdate but this did not change anything. My slides come from this.props and are built using a map call

        const swiperParams = {
            slidesPerView: 3,
            grabCursor: true,
            loop: false,
            direction: 'horizontal',
            watchOverflow: true,
            spaceBetween: 30,
            pagination: {
                el: '.swiper-pagination',
                type: 'bullets',
                clickable: true
            },
            breakpoints: {
                480: {
                    slidesPerView: 1,
                    spaceBetween: 20
                },
                // when window width is <= 1024px
                1024: {
                    slidesPerView: 2,
                    spaceBetween: 30
                }
            },
            containerClass: 'swiper-container promo',
            rebuildOnUpdate: true,
            shouldSwiperUpdate: true
        }

This is the map generating the slides

        let slides = ''
        if (this.props.images.length > 0) {
            slides = (
                this.props.images.map((imageRecord, index) => {
                    return (
                        <div key={index}>
                            <img src={imageRecord['thumb']} className="img-fluid light-shadow" alt={imageRecord['title']} />
                            <div className="swiper-hover" onClick={this.openLightbox.bind(this, index)}>
                                <i className="icon icon-zoom-in icon-2x"></i>
                            </div>
                        </div>
                    )
                })
            )
        }

and this is the swiper call when rendering it

<Swiper {...swiperParams}>
     {slides}
</Swiper>

In the following screenshots you can see the initial view which shows all slides and ignores the slidesPerView = 3 settings, and once I resize and restore the page, they display correctly
Before
initial_view
After resize
resized_view

Is there any method or param that I'm missing that would properly update the swiper once all the dynamic slides are in place?

Most helpful comment

I think you should not render Slide when images is empty.

render() {
     return this.props.images.length  > 0  ? <Swiper>....</Swiper> : false 
}

All 11 comments

actually I get the same display if I use a static list of slides, so it's not really linked to them being created dinamically by the map. it's as if a refresh or an initial render method is not called during the swiper's initialization

I have some issues with slidesPerView+breakpoints as well - for me it always loads 1 slide for a split second, then loads the proper number of slides. But if the proper number of slides is 1 (based on window size), this jarring rendering does not happen.

This is with GatsbyJS and firebase hosting. But when I'm developing locally (gatsby develop command), this jarring animation doesn't happen. Could be a weird build error, weird cache, etc.

Hi @pixelplant , can u provide any live demo ?

@pixelplant , try to render Swipper component only if there is above zero images

{
   this.props.images.length > 0 && (
    <Swiper {...swiperParams}>
      {slides}
    </Swiper>
  )
  }

I think you should not render Slide when images is empty.

render() {
     return this.props.images.length  > 0  ? <Swiper>....</Swiper> : false 
}

I have a similar issue, my workaround was to update the swiper after first render:

Add a reference:

<Swiper ref={(node) => { if (node) this.swiper = node.swiper; }}>

Then update after componentDidMount:

componentDidMount() {
    setTimeout(() => this.swiper.update());
}

The action is wrapped by a setTimeout because I want to push this action to the top of the execution queue.

I have a similar issue if I using breakpoints my swiper is crashed on load until resize window, but if comment code with breakpoints everythings works fine.

This i have on load
image

It's mine component with slider:

class Reviews extends Component {

  render() {
    const params = {
      slidesPerView: 2,
      centeredSlides: false,
      effect: 'slide',
      loop: true,
      spaceBetween: 40,
      shouldSwiperUpdate: true,
      rebuildOnUpdate: true,
      navigation: {
        nextEl: '.reviews__slider__nav--next',
        prevEl: '.reviews__slider__nav--prev'
      },
      renderPrevButton: () => (
        <a className="reviews__slider__nav reviews__slider__nav--prev"></a>
      ),
      renderNextButton: () => (
        <a className="reviews__slider__nav reviews__slider__nav--next"></a>
      ),
      breakpoints: {
        959: {
          slidesPerView: 1,
          centeredSlides: true,
          spaceBetween: 0,
          // width: auto
        }
      }
    }
    return (
      <div className='about__reviews'>

        <div className='reviews__slider'>
          <Swiper
            {...params}>
            <div>
              <ReviewItem
                userName='Agnieszka'
                text='Lorem ipsum dolor sit amet, consectet adipiscing elit. Sem consectetur commodo. Etiam venenatis viverra dui hendrerit lectus, id malesuada mauris.'
                type='facebook'
              />
            </div>
            <div>
              <ReviewItem
                userName='Tomek'
                text='Lorem ipsum dolor sit amet, consectet adipiscing elit. Sem consectetur commodo. Etiam venenatis viverra dui hendrerit lectus, id malesuada mauris.'
                type='google' />
            </div>
            <div>
              <ReviewItem
                userName='Bonfiacy'
                text='Lorem ipsum dolor sit amet, consectet adipiscing elit. Sem consectetur commodo. Etiam venenatis viverra dui hendrerit lectus, id malesuada mauris.'
                type='facebook' />
            </div>
            <div>
              <ReviewItem
                userName='Lucyna'
                text='Lorem ipsum dolor sit amet, consectet adipiscing elit. Sem consectetur commodo. Etiam venenatis viverra dui hendrerit lectus, id malesuada mauris.'
                type='google' />
            </div>
            <div>
              <ReviewItem
                userName='Barbara'
                text='Lorem ipsum dolor sit amet, consectet adipiscing elit. Sem consectetur commodo. Etiam venenatis viverra dui hendrerit lectus, id malesuada mauris.'
                type='facebook' />
            </div>
          </Swiper>
        </div>
      </div>
    );
  }
}

@hedshafran , you don't need to do so. Instead, please use param { rebuildOnUpdate: true }

@czesuaf92 , I think you should provide initial param { slidesPerView: number of slide u want to show originally }

Have you solve this issue?? I am having same error please help and its not solving by check length of array I am already doing it.

{ books && books.length > 0 &&(


{ books.length>0 && books.map((book: TBook) => (




))

)}
thanks

@FazilaMehtab maybe it will help someone else, so I'll leave a solution of this issue here:

Setting prop observer={true} or just observer for <Swipper> works for me

Was this page helpful?
0 / 5 - 0 ratings