[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:
- Created 3 years ago
- Reactions:2
- Comments:65 (1 by maintainers)
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:
Another way to solve this problem: