How to use useSwiper outside a Swiper instance?

Viewed 4392

I'm using Swiper for React to show some slides.

I'm stuck at using external buttons to navigate between slides (previous and next).

Swiper has a useSwiper hook that can provide programmatic access to its Swiper instance API. But it does not work.

Here's my code:

import { useSwiper } from 'swiper/react';

//more code

const swiper = useSwiper();

//more code

<Swiper
    modules={[Navigation, Pagination, Scrollbar, A11y]}
    navigation
    spaceBetween={20}
    slidesPerView={1}
>
    <button onClick={() => swiper.slideNext()}>Slide</button>
    {
        ads.map(ad => <SwiperSlide>
            slider explanation
        </SwiperSlide>
    )}
</Swiper>      

And when I click the button, I receive this error:

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

2 Answers

useSwiper must be used by components inside a Swiper element.

So something like the following

import { useSwiper } from "swiper/react";

const SwiperButtonNext = ({ children }) => {
  const swiper = useSwiper();
  return <button onClick={() => swiper.slideNext()}>{children}</button>;
};

and then use that inside the Swiper

<Swiper
  modules={[Navigation, Pagination, Scrollbar, A11y]}
  navigation
  spaceBetween={20}
  slidesPerView={1}
>
  <SwiperButtonNext>Slide</SwiperButtonNext>
  {ads.map((ad) => (
    <SwiperSlide>slider explanation</SwiperSlide>
  ))}
</Swiper>;

That is because Swiper creates a context and the useSwiper hook tries to consume that context, so it needs to be called from a child of the context provider.

You can use the onSwiper event for the Swiper component to save the swiper instance with React.useState and then pass this instance as a prop to swiper next/prev buttons component.

<Swiper                     
  onSwiper={(swiper) => setSwiperInstance(swiper)}
>
   ...slides
</Swiper>
Related