question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[swiper/react] Custom navigation/pagination components using React refs not working/possible?

See original GitHub issue
  • Swiper Version: 6.2.0
  • Platform/Target and Browser Versions: All

Also posten on Stackoverflow: Swiper React | How to create custom navigation/pagination components using React refs?

What you did

const MySwiper = () => {
  const navigationPrevRef = React.useRef(null)
  const navigationNextRef = React.useRef(null)

  return (
    <Swiper
      navigation={{
        prevEl: navigationPrevRef.current,
        nextEl: navigationNextRef.current,
      }}
    >
      <SwiperSlide>slide 1</SwiperSlide>
      <SwiperSlide>slide 2</SwiperSlide>
      <div ref={navigationPrevRef} />
      <div ref={navigationNextRef} />
    </Swiper>
  )
}

Expected Behavior

To work

Actual Behavior

Did not work


SwiperJS documentation states that navigation prevEl/nextEl can either be of type “string” or “HTMLElement”. Using HTML nodes allows for navigation prevEl/nextEl to be scoped to each rendered instance of MySwiper. In React this is usually done with “refs”.

const App = () => (
  <div>
    <MySwiper /> // MySwiper1
    <MySwiper /> // MySwiper2
  </div>
)

In the App example above, navigation prevEl/nextEl from “MySwiper2” should not trigger sliding of “MySwiper1”, which is what would happen if one would have used string selectors like { prevEl: '.prev', nextEl: '.next' }. Obviously (if even possible within the application) one could generate unique classnames. A better solution would be to pass the HTML elements as these are already unique. Is this possible somehow with React refs?

My current hacky workaround:

const MySwiper = () => {
  const navigationPrevRef = React.useRef(null)
  const navigationNextRef = React.useRef(null)

  return (
    <Swiper
      navigation={{
        // Both prevEl & nextEl are null at render so this does not work
        prevEl: navigationPrevRef.current,
        nextEl: navigationNextRef.current,
      }}
      onSwiper={(swiper) => {
        // Delay execution for the refs to be defined
        setTimeout(() => {
          // Override prevEl & nextEl now that refs are defined
          swiper.params.navigation.prevEl = navigationPrevRef.current
          swiper.params.navigation.nextEl = navigationNextRef.current

          // Re-init navigation
          swiper.navigation.destroy()
          swiper.navigation.init()
          swiper.navigation.update()
        })
      }}
    >
      <SwiperSlide>slide 1</SwiperSlide>
      <SwiperSlide>slide 2</SwiperSlide>
      <div ref={navigationPrevRef} />
      <div ref={navigationNextRef} />
    </Swiper>
  )
}

Thanks in advance!

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:65 (1 by maintainers)

github_iconTop GitHub Comments

101reactions
mistvalcommented, Apr 27, 2021

I was having a hard time getting some of the above examples to work. I ended up using the slidePrev() and slideNext() functions like this:

const swiperRef = React.useRef(null);

return (
  <>
    <div id="previousButton" onClick={() => swiperRef.current.swiper.slidePrev()} />
    <div id="nextButton" onClick={() => swiperRef.current.swiper.slideNext()} />
    <Swiper
      ref={swiperRef}
    >
      <SwiperSlide>
        Slide 1
      </SwiperSlide>
      <SwiperSlide>
        Slide 2
      </SwiperSlide>
    </Swiper>
  </>
)
89reactions
joe511230commented, Dec 7, 2021

Another way to solve this problem:

// use the `useState` hook instead of `useRef`
const [prevEl, setPrevEl] = useState<HTMLElement | null>(null)
const [nextEl, setPrevEl] = useState<HTMLElement | null>(null)
<Swiper navigation={{ prevEl, nextEl }}>
// some slides
</Swiper>
<div ref={(node) => setPrevEl(node)}>prev</div>
<div ref={(node) => setNextEl(node)}>next</div>
Read more comments on GitHub >

github_iconTop Results From Across the Web

Swiper React | How to create custom navigation/pagination ...
Here's an updated example using React v18 + Swiper v8.4.4 (not recommended). import { Swiper, SwiperSlide } from 'swiper/react'; ...
Read more >
Swiper React Components
Swiper is the most modern free mobile touch slider with hardware accelerated transitions and amazing native behavior.
Read more >
Swiper React | How to create custom navigation/pagination ...
... React | How to create custom navigation/pagination components using React refs? ... Passing refs directly is apparently not possible in Swiper v6.2.0....
Read more >
Swiperjs Pagination And Navigation Buttons Not Working
Solvedswiper [swiper/react] Custom navigation/pagination components using React refs not working/possible? Accepted Answer Other Answers: Related Issues:.
Read more >
Swiper Navigator(화살표) 바깥으로 빼기 - homie's blog
[swiper/react] Custom navigation/pagination components using React refs not working/possible? · Issue #3855 · nolimits4web/swi.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found