I'm trying to integrate a custom pagination component with Swiper with no success.
The custom pagination component renders a prev and a next button with also the number of the current slide and the total number of pages:
type ArrowPaginationProps = {
current: number;
total: number;
onClickPrev: () => void;
onClickNext: () => void;
};
export const ArrowPagination = (props: ArrowPaginationProps) => {
return (
<div className="arrow-pagination">
<button type="button" onClick={props.onClickPrev}>
Prev
</button>
<div className="arrow-pagination-label">
{props.current} / {props.total}
</div>
<button type="button" onClick={props.onClickNext}>
Next
</button>
</div>
);
};
And this what I've done to integrate it with swiper:
import React, { useState } from "react";
// Import Swiper React components
import { Swiper, SwiperSlide, SwiperClass } from "swiper/react";
import { Controller } from "swiper/modules";
import { ArrowPagination } from "./ArrowPagination";
// Import Swiper styles
import "swiper/css";
import "./styles.css";
export default function App() {
const [controlledSwiper, setControlledSwiper] = useState<SwiperClass>(null);
const handleClickPrev = () => controlledSwiper.slidePrev();
const handleClickNext = () => controlledSwiper.slideNext();
return (
<>
<Swiper
modules={[Controller]}
controller={{ control: controlledSwiper }}
onSwiper={setControlledSwiper}
>
{slides.map((text, idx) => {
return <SwiperSlide key={idx}>{text}</SwiperSlide>;
})}
<div slot="container-end">
<ArrowPagination
current={controlledSwiper?.activeIndex + 1}
total={slides.length}
onClickPrev={handleClickPrev}
onClickNext={handleClickNext}
/>
</div>
</Swiper>
</>
);
}
const slides = [
"Slide 1",
"Slide 2",
"Slide 3",
"Slide 4",
"Slide 5",
"Slide 6",
"Slide 7",
"Slide 8",
"Slide 9",
"Slide 10",
];
The issue is that, when I click the prev or next button, the current
page number is not being updated.
Reproducible sandbox here: https://codesandbox.io/p/sandbox/react-swipper-custom-pagination-hq73hw
Try this approach:
import React, { useState } from "react";
import { Swiper, SwiperSlide, SwiperClass } from "swiper/react";
import { Controller } from "swiper/modules";
import { ArrowPagination } from "./ArrowPagination";
import "swiper/css";
import "./styles.css";
export default function App() {
const [controlledSwiper, setControlledSwiper] = useState<SwiperClass>(null);
const [activeIndex, setActiveIndex] = useState(0);
const handleClickPrev = () => controlledSwiper.slidePrev();
const handleClickNext = () => controlledSwiper.slideNext();
const handleSlideChange = () => {
setActiveIndex(controlledSwiper?.activeIndex || 0);
};
return (
<>
<Swiper
modules={[Controller]}
controller={{ control: controlledSwiper }}
onSwiper={setControlledSwiper}
onSlideChange={handleSlideChange}
>
{slides.map((text, idx) => {
return <SwiperSlide key={idx}>{text}</SwiperSlide>;
})}
</Swiper>
<ArrowPagination
current={activeIndex + 1}
total={slides.length}
onClickPrev={handleClickPrev}
onClickNext={handleClickNext}
/>
</>
);
}
https://codesandbox.io/p/sandbox/react-swipper-custom-pagination-forked-vp7l7f?file=%2Fsrc%2FApp.tsx