React-id-swiper: rebuildOnUpdate causes errors in conjunction with setSwiper because of infinite rerender loop

Created on 8 Aug 2019  路  8Comments  路  Source: kidjp85/react-id-swiper

Setting rebuildOnUpdate to cause Swiper to take into account changes in props on render causes errors within swiper.

swiper.esm.bundle.js:1306 Uncaught TypeError: Cannot read property 'slidesPerGroup' of undefined
    at Swiper.slideTo (swiper.esm.bundle.js:1306)
    at eval (contents.tsx:40)
    at eval (contents.tsx:45)
    at commitHookEffectList (react-dom.development.js:17283)
    at commitPassiveHookEffects (react-dom.development.js:17307)
    at HTMLUnknownElement.callCallback (react-dom.development.js:149)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:199)
    at invokeGuardedCallback (react-dom.development.js:256)
    at commitPassiveEffects (react-dom.development.js:18774)
    at wrapped (scheduler-tracing.development.js:207)

When I removed getSwiper={setSwiper} it worked perfectly well (but I need that swiperInstance in my parent component). When I add it back, but use a totally stripped back Swiper with no props other than rebuildOnUpdate and getSwiper with nothing happening to that swiper, the error goes away, but I noticed that there is an infinite render loop causing my console logs to fire repeatedly, so I decided to investigate that.

In your code it looks like in rebuildSwiper, both buildSwiper and destroySwiper are calling getSwiperInstance which causes a rerender in my parent component, which causes Swiper to rerender, causing that useEffect to fire again, causing rebuildSwiper to run once again etc. etc.

When I set stricter deps in that useEffect, that infinite rerender stops happening and the error goes away.

If you'd like, I can do a fork and create a pull request with my fix?

Most helpful comment

The render loop does not occur anymore. But getSwiper does still not work properly with rebuildOnUpdate because it will always set the Swiper instance to the destroyed instance.

All 8 comments

Please make a pull request for this if you can. Thank you

This sounds like the same issue I am experiencing- I am fetching data from an API and when I try and map this data within the Carousel, I get the error:
Unhandled Rejection (Error): Rendered more hooks than during the previous render.

@patrickbenjamin1 did you find a fix for this? Any help much appreciated!

I think it should be fixed in newest version 2.4.0

The render loop does not occur anymore. But getSwiper does still not work properly with rebuildOnUpdate because it will always set the Swiper instance to the destroyed instance.

I'm facing the issue mentioned by @Awem

I looked at the source code, and I feel that the culprit is this useEffect:

useEffect(() => {
  getSwiperInstance(swiperInstanceRef.current);
}, [swiperInstanceRef]);

When a rebuild is triggered, destroySwiper and buildSwiper are called in sequence, and these mutate swiperInstanceRef.current, but this doesn't trigger the above effect.

@kidjp85 I really hope this issue could be addressed (I'm no expert, but perhaps adding swiperInstanceRef.current to the dependency list may fix this?

Edit
I just tried this, and I got a render loop.
I guess the fix may be a little more involved.

Okay, necroing...

To fix this, I had to modify the code to manually call getSwiperInstance(swiperInstanceRef.current); as a hack in multiple places where the swiper instance changes. Not elegant, but partially got the job done...

There are far too many problems with this library that I had to patch over and hack around on top of this.

@Awem That is what rebuildOnUpdate being used for. If you don't want Swiper instance to be destroyed, let use shouldSwiperUpdate instead

With newest version, getSwiper now is deprecated.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mbenjrinija picture mbenjrinija  路  4Comments

xinconan picture xinconan  路  6Comments

davemin picture davemin  路  6Comments

maheshambiga picture maheshambiga  路  4Comments

cweise picture cweise  路  6Comments