3

I have been trying to create a Swiper that utilizes Swiper.js' autoplay functionality to stop and play, in React. I followed their instructions as best I could and did lots of research trying to find an answer. I was even able to confirm my setup (somewhat) through a jQuery example that does the same thing, but even that reference didn't help in React.

Here's what I've got so far:

// Note: I am using Next.js,
// so there are some minor differences from React,
// but they shouldn't affect the Swiper.
import { useRef } from 'react'
import { Swiper, SwiperSlide } from 'swiper/react'
import { Autoplay, Pagination, EffectCreative } from 'swiper'
import 'swiper/css'
import 'swiper/css/pagination'

const App = () => {

  const heroSwiper = useRef(null)

  // Both functions below return an error:
  // TypeError: undefined is not an object
  // (evaluating 'heroSwiper.current.autoplay.start')
  const playHero = () => {
    heroSwiper.current.autoplay.start()
  }
  const pauseHero = () => {
    heroSwiper.current.autoplay.stop()
  }

  return (
    <>

      // ... Other content

      <Swiper
        ref={heroSwiper}
        direction='horizontal'
        speed={2500}
        loop={true}
        grabCursor={true}
        autoplay={{
          disableOnInteraction: false,
          delay: 3500
        }}
        effect={'creative'}
        creativeEffect={{
          prev: {
            translate: ['-50%', 0, -100],
          },
          next: {
            translate: ['100%', 0, 0],
          }
        }}
        pagination={{
          clickable: true,
        }}
        modules={[ Autoplay, EffectCreative, Pagination ]}
      >

        <SwiperSlide>
          <span>1</span>
        </SwiperSlide>
        <SwiperSlide>
          <span>2</span>
        </SwiperSlide>
        <SwiperSlide>
          <span>3</span>
        </SwiperSlide>
        <SwiperSlide>
          <span>4</span>
        </SwiperSlide>
        <SwiperSlide>
          <span>5</span>
        </SwiperSlide>
        <SwiperSlide>
          <span>6</span>
        </SwiperSlide>

        <div>
          <button type='button' onPointerUp={playHero}>Play</button>
          <button type='button' onPointerUp={pauseHero}>Pause</button>
        </div>

      </Swiper>

      // ... Other content

    </>
  )
}

export default App

Thanks for the responses!

2 Answers 2

4

I figured it out! In Swiper.js' JavaScript example, they use a constant to reference the Swiper function—not the element.

const swiper = new Swiper('.swiper', {
 autoplay: {
   delay: 5000,
 },
})

This was confusing to me, since in React, Swiper.js handles the initialization.

Thankfully, I found—in a different section—they said "After you initialize Swiper it is possible to access to Swiper's instance on its HTMLElement. It is swiper property of Swiper's HTML container element:"

const swiper = document.querySelector('.swiper').swiper

Seeing how they reference swiper inside the element made me realize that I just needed to reference swiper inside my reference.

const playHero = e => {
  e.preventDefault()
  heroSwiper.current.swiper.autoplay.start()
}
const pauseHero = e => {
  e.preventDefault()
  heroSwiper.current.swiper.autoplay.stop()
}

It makes sense, but their documentation doesn't make this clear, since it's written in vanilla JavaScript only.

I hope this helps anyone else having this issue.

1
  • That's the solution I've been looking for. Thanks.
    – MohamedZh
    Jun 22, 2023 at 18:06
0

There is a mistake to use ref for swiper component.

Use a state variable instead of const heroSwiper = useRef(null);

const [heroSwiper, setSwiperRef] = useState(null);

And then set setSwiperRef in onSwiper prop.

<Swiper
  // ref={heroSwiper} // This is wrong
  onSwiper={setSwiperRef}

Finally, use the state variable to change start/stop of slider.

  const playHero = () => {
    heroSwiper.autoplay.start();
  };
  const pauseHero = () => {
    heroSwiper.autoplay.stop();
  };

Please let me know if it works!

4
  • This is a good idea, I don't think you understand how Swiper.js works. Swiper.js' documentation only gives specific use cases in vanilla JavaScript, but it is clear that all I need to have is a reference to the element. Using states won't make a difference in this case. Thanks for the idea, though!
    – andrilla
    Jul 25, 2022 at 16:06
  • This is not my idea and is described in the Swiper.js documentation. Not sure what you actually need. Good luck.
    – Liki Crus
    Jul 25, 2022 at 16:15
  • Really? Can you send a link to this? I couldn't find anything on this in their documentation.
    – andrilla
    Jul 27, 2022 at 14:39
  • 1
    @andrilla, swiperjs.com/demos#manipulation and my sandbox based on it's code for you. codesandbox.io/s/swiper-manipulation-react-forked-59tfjm?file=/…
    – Liki Crus
    Jul 27, 2022 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.