Как сделать переход к нужному слайду в swaper React TS по нажатию на div?

Как сделать произвольное переключение слайдов в swaper ?

Не работает, и там просто цифры, а мне нужно будет маленькие картинки слайдов ставить в отличие от цифр

 const pagination = {
    clickable: true,
    renderBullet: function (index: number) {
      return '<span>' + (index + 1) + '</span>';
    },
  };

  return (
    <div className="swiper-container">
      <Swiper
        slidesPerView={'auto'}
        spaceBetween={20}
        centeredSlides={true}
        centeredSlidesBounds={true}
        navigation={true}
        mousewheel={true}
        scrollbar={{
          hide: true,
        }}
        pagination={pagination}
        autoHeight={true}
        modules={[Scrollbar, Navigation, Mousewheel, Pagination]}
        className="mySwiper"
      >
        <SwiperSlide>
          <img src={MyImage1} alt="horse" />
        </SwiperSlide>
        <SwiperSlide>
          <img src={MyImage2} alt="horse" />
        </SwiperSlide>
        <SwiperSlide>
          <img src={MyImage3} alt="horse" />
        </SwiperSlide>
        <SwiperSlide>
          <img src={MyImage4} alt="horse" />
        </SwiperSlide>
      </Swiper>
    </div>
  );

Пробовал таким образом вызывает ошибку

Cannot read properties of null (reading 'slideTo') TypeError: Cannot read properties of null (reading 'slideTo')

interface ISwiperButtonProps {
  index: number;
  children: React.ReactNode;
}

const SwiperButton = ({ index, children }: ISwiperButtonProps) => {
  const swiper = useSwiper();
  return <button onClick={() => swiper.slideTo(index)}>{children}</button>;
};

interface ISliderProps {}

const Slider: React.FC<ISliderProps> = ({}: ISliderProps) => {
//   const swiperRef = useRef<typeof Swiper | null>(null);

//   const [controlledSwiper, setControlledSwiper] = useState(null);
//   const swiper = useSwiper();
//   const goToSlide = (index: number) => {
//     console.log('qwe');
//     swiper.slideTo(index);
//     // if (swiperRef.current) {
//     //   swiperRef.current.slideTo(index);
//     // }
//   };

  return (
    <div className="swiper-container">
      <Swiper
        slidesPerView={'auto'}
        spaceBetween={20}
        centeredSlides={true}
        centeredSlidesBounds={true}
        navigation={true}
        scrollbar={{
          hide: true,
        }}
        autoHeight={true}
        modules={[Scrollbar, Navigation, Controller]}
        className="mySwiper"
      >
        <SwiperSlide>
          <img src={MyImage1} alt="horse" />
        </SwiperSlide>
        <SwiperSlide>
          <img src={MyImage2} alt="horse" />
        </SwiperSlide>
        <SwiperSlide>
          <img src={MyImage3} alt="horse" />
        </SwiperSlide>
        <SwiperSlide>
          <img src={MyImage4} alt="horse" />
        </SwiperSlide>
      </Swiper>
      <SwiperButton index={1}>asd</SwiperButton>
    </div>
  );

Ответы (1 шт):

Автор решения: Arbery

Есть 2 варианта решения:

  1. Кнопки с хуком useSwiper() - <SwiperButton index={1}>asd</SwiperButton> должны быть внутри <Swiper></Swiper> - тогда использование () => swiper.slideTo(index) сработает
  2. использовать useRef
const swiperRef = useRef();

Самому слайдеру:

onSwiper={(swiper) => {
  swiperRef.current = swiper;
}}

Кнопкам:

<button onClick={handleSwiperTo(1)}>1</button>

Обработчик кнопок:

const handleSwiperTo = (index) => {
  return () => swiperRef.current.slideTo(index - 1);
};

А в общем:

import { useRef } from "react";
import { Swiper, SwiperSlide, useSwiper } from "swiper/react";
import { Scrollbar, Navigation, Mousewheel, Pagination } from "swiper/modules";
import "swiper/css";

export default function App() {
  const swiperRef = useRef();

  const handleSwiperTo = (index) => {
    return () => swiperRef.current.slideTo(index);
  };

  return (
    <div className="App">
      <Swiper
        slidesPerView={"auto"}
        spaceBetween={20}
        centeredSlides={true}
        centeredSlidesBounds={true}
        navigation={true}
        mousewheel={true}
        scrollbar={{
          hide: true,
        }}
        onSwiper={(swiper) => {
          swiperRef.current = swiper;
        }}
        autoHeight={true}
        modules={[Scrollbar, Navigation, Mousewheel, Pagination]}
        className="mySwiper"
      >
        <SwiperSlide>
          <img src="https://i.imgur.com/6raORdA.jpeg" alt="horse" />1
        </SwiperSlide>
        <SwiperSlide>
          <img src="https://i.imgur.com/6raORdA.jpeg" alt="horse" />2
        </SwiperSlide>
        <SwiperSlide>
          <img src="https://i.imgur.com/6raORdA.jpeg" alt="horse" />3
        </SwiperSlide>
        <SwiperSlide>
          <img src="https://i.imgur.com/6raORdA.jpeg" alt="horse" />4
        </SwiperSlide>
      </Swiper>
      <button onClick={handleSwiperTo(1)}>1</button>
      <button onClick={handleSwiperTo(2)}>2</button>
      <button onClick={handleSwiperTo(3)}>3</button>
      <button onClick={handleSwiperTo(4)}>4</button>
    </div>
  );
}

В рабочем виде на Codesandbox

→ Ссылка