본문 바로가기

디버깅노트

[solved] swiper를 map 함수로 감쌀 때 navigation lock disable 되는 현상

반응형

슬라이드 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()를 해줌으로써 문제를 해결했다. 

반응형