kidjp85 / react-id-swiper

A library to use idangerous Swiper as a ReactJs component which allows Swiper's modules custom build
https://react-id-swiper.ashernguyen.site/
MIT License
1.49k stars 154 forks source link

How to get/create instance after destroyed swiper? #504

Closed selensr closed 2 years ago

selensr commented 2 years ago

Hi,

I am struggling with an issue about updating react-id-swiper. I need to update swiper as the data changed, so I turned rebuilOnUpdate to true. It worked, but also I need to reach the swiper instance to attach different event handlers to pagination. However, after turning rebuildOnUpdate true, I couldn't catch the new instance. Swiper is just coming as {destroyed: true}. How can I reach the new instance and maintain my events on that? The getSwiper() method brings same result which is Swiper {destroyed: true}, and as mentioned on previous issues I can't use ref, it's always returning null.

This is the relevant code sample:

const Slider = ({ slides, shouldSliderUpdate }) => {
  const ref = useRef(null);
  const [swiper, setSwiper] = useState(null);
  const [config, setConfig] = useState(null);

  const getConfigs = slideData => {
    return {
      rebuildOnUpdate: true,
      watchSlidesVisibility: true,
      observer: true,
      observeParents: true,
      pagination: getPaginationConfigs(slideData),
    };
  };

  useEffect(() => {
    setConfig(getConfigs(slides));
  }, [shouldSliderUpdate]);

  useEffect(() => {
    if (isDomLoaded && config && !swiper) {
      const swiperInstance = document.querySelector('.swiper-container')?.swiper;
      setSwiper(swiperInstance);
    }
  }, [isDomLoaded, config]);

  useEffect(() => {
    if (swiper) {
      const thumbnails = document.querySelector('.slider-pagination');
      if (thumbnails) {
        attachMouseEventToThumbnails('mouseover', thumbnails, swiper);
        attachMouseEventToThumbnails('click', thumbnails, swiper);
      }
    }
  }, [swiper]);

  return (
    <Swiper getSwiper={setSwiper} ref={ref} {...config}>
      {slides}
    </Swiper>
  );
};

The problem is here, I can't use attachMouseEventToThumbnails() functions because swiper is returning as destroyed so that the mouse events is not working. Is there any solution to reach out to new instance of swiper or should I create new one?

selensr commented 2 years ago

Apparently, after using rebuildOnUpdate: true, you can't access current instance by using ref or getSwiper or document, but we could reach the instance from init() method. As mentioned Swiper Api, that this keyword within event handler always points to current Swiper instance.

const swiper = new Swiper('.swiper', {
  // ...
  on: {
    init: function () {
      console.log('swiper initialized', this);
    },
  },
});