Search code examples
javascriptreactjscarousel

Problem with carousel with thumbs (react-id-swiper)


I'm trying to make a carousel with 'react-id-swiper' component with thumbs, but it seems that there is no connection between the main carousel and the carousel with thumbs.

I searched out all over the internet with no luck. Also scanned the documentation of "react-id-swiper" and all the reported issues at this component's github.

import React from "react";
import styles from "./Gallery.css";
import Swiper from "react-id-swiper";
import("react-id-swiper/src/styles/css/swiper.css");
import { Navigation } from "swiper/dist/js/swiper.esm";

import "../styles.css";

export default class Gallery extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      gallerySwiper: null,
      thumbnailSwiper: null
    };
  }

  componentWillUpdate(nextProps, nextState) {
    if (nextState.gallerySwiper && nextState.thumbnailSwiper) {
      const { gallerySwiper, thumbnailSwiper } = nextState;

      gallerySwiper.controller.control = thumbnailSwiper;
      thumbnailSwiper.controller.control = gallerySwiper;
    }
  }

  galleryRef = ref => {
    if (ref) this.setState({ gallerySwiper: ref.swiper });
  };

  thumbRef = ref => {
    if (ref) this.setState({ thumbnailSwiper: ref.swiper });
  };

  render() {
    const thumbnailSwiperParams = {
      paceBetween: 10,
      centeredSlides: true,
      slidesPerView: "auto",
      touchRatio: 0.2,
      slideToClickedSlide: true,
      onInit: swiper => {
        this.swiper2 = swiper;
      }
    };

    const params = {
      modules: [Navigation],
      slidesPerView: 1,
      zoom: {
        maxRatio: 5
      },
      spaceBetween: 30,
      loop: true,
      navigation: {
        nextEl: ".swiper-button-next",
        prevEl: ".swiper-button-prev"
      },
      onInit: swiper => {
        this.swiper1 = swiper;
      }
    };

    return (
      <React.Fragment>
        <div className="gallery-wrapper">
          <Swiper {...params} ref={this.galleryRef}>
            <div className="swiper-slide">
              <img src="http://lorempixel.com/800/800/sports/1/" />
            </div>
            <div className="swiper-slide">
              <img src="http://lorempixel.com/800/400/sports/2/" />
            </div>
            <div className="swiper-slide">
              <img src="http://lorempixel.com/400/800/sports/3/" />
            </div>
          </Swiper>
        </div>
        <div className="thumbs-container">
          <Swiper {...thumbnailSwiperParams} ref={this.thumbRef}>
            <div className="swiper-slide1">
              <img src="http://lorempixel.com/100/100/sports/1/" />
            </div>
            <div className="swiper-slide1">
              <img src="http://lorempixel.com/100/100/sports/2/" />
            </div>
            <div className="swiper-slide1">
              <img src="http://lorempixel.com/100/100/sports/3/" />
            </div>
          </Swiper>
        </div>
      </React.Fragment>
    );
  }
}

Also you can see a demo: https://codesandbox.io/s/74mz4jz646

This is the official code examples: http://kidjp85.github.io/react-id-swiper/ ("Thumbs Gallery With Two-way Control")

UPD: ok guys, Swiper is not really 100% good for thumbnails. So I just decided to use react-slick with build-in thumbs functionality. You can find example in the react-slick docs.


Solution

  • For someone with this issue when you use custom build you have to import the modules manually, but in the examples they use the library that imports everything

    To solve this issue just add into module imports:

    // For version <=2.3.2
    import { Swiper, Controller } from 'swiper/dist/js/swiper.esm';
    // For version >=2.4.0
    import { Swiper, Controller } from 'swiper/js/swiper.esm';
    

    And inside the slider settings

    const gallerySwiperParams = {
            Swiper,
            modules: [Controller],
            getSwiper: getGallerySwiper,
            navigation: {
              nextEl: '.swiper-button-next',
              prevEl: '.swiper-button-prev',
            },
            spaceBetween: 10,
          };
    

    modules: [Controller], this makes the magic