슬라이드 UI가 필요할때 swiper 라이브러리를 종종 쓰고 있는데,
요번에 작업하면서 생각지도 못했던 에러가 발생해 기록해보고자 한다.
<Swiper
navigation={true}
slidesPerView={2}
spaceBetween={20}
modules={[Navigation]}
>
{items.map((item, index) => (
<SwiperSlide key={index}>
<div>{item.title}</div>
</SwiperSlide>
)}
</Swiper>
위와 같은 형식으로 배열을 map으로 리턴하는 값들을 Swiper 안에 담았다.
슬라이드는 문제없이 불러와지는데, 문제는 navigation 버튼들이 활성화가 안 되는 것이다.
제공되는 네비게이션 버튼의 기본 클래스명은 swiper-button-next, swiper-button-prev인 것을 확인할 수 있었는데,
map으로 불러와진 리턴값을 슬라이드에 넣으면 초기 로딩 때 이 클래스에 lock과 disabled 클래스명도 함께 적용되는 걸 알 수 있었다.
lock과 disabled가 되면 비활성화와 관련된 css가 적용된다. (클릭 이벤트도 막고 있음)
방법1.
초기 랜딩 때 클래스를 임의로 remove 시키는 코드를 짜봤는데 먹히지 않았다.
방법2.
그 다음 ref로 swiper 객체를 불러다가 update()를 해봤는데도 통하지 않았다.
방법3.
swiper 객체를 불러다가, 이번에는 navigation을 update()했는데 해결됐다.
const swiperRef = useRef<SwiperRef>(null);
useEffect(() => {
if (swiperRef.current) {
setTimeout(() => {
swiperRef.current?.swiper.navigation.update();
}, 1000);
}
}, []);
...
<Swiper
navigation={true}
slidesPerView={2}
spaceBetween={20}
modules={[Navigation]}
ref={swiperRef}
>
{items.map((item, index) => (
<SwiperSlide key={index}>
<div>{item.title}</div>
</SwiperSlide>
)}
</Swiper>
처음 navigation이 init될때랑 map의 리턴값이 나올 때의 타이밍이 맞지 않았나 보다.
슬라이드의 갯수나 너비 등의 정보가 담기지 않아 전부 비활성화되는 것 같다.
그래서 한번 로딩된 이후에 1초 뒤(이건 혹시몰라 시간차를 좀 더 두기 위해 내가 임의로 setTimeout 설정을 해줬다.)에 navigation.update()를 해줌으로써 문제를 해결했다.