스와이퍼 반응형 이슈 해결: 왜 직접 swiper 인스턴스를 써야 할까?

강 진성·2025년 4월 21일

Swiper로 반응형 슬라이드를 구현하면서, 리사이징을 빠르게 할 때 슬라이드들이 무너지는 현상을 만났다. 이번 글에서는 그 이유와 해결 방법을 간단하게 정리했다.


문제 상황


아래 그림은 현재 처한 문제이다.

Swiper로 슬라이드를 만들 때 다음과 같이 설정했다.

<Swiper
  modules={[Navigation, Autoplay]}
  navigation={{
    nextEl: ".swiper-custom-next",
    prevEl: ".swiper-custom-prev",
  }}
  spaceBetween={30}
  breakpoints={{
    1536: { slidesPerView: 4 },
    1280: { slidesPerView: 3 },
    768: { slidesPerView: 2 },
    0: { slidesPerView: 1 },
  }}
  loop={true}
  autoplay={{ delay: 3000, disableOnInteraction: false }}
  onSlideChange={(swiper) => setActiveIndex(swiper.realIndex)}
  speed={1000}
  allowTouchMove={false}
  onSwiper={(swiper) => (contentSwiperRef.current = swiper)}
>

리사이징이 빠르게 발생하면 슬라이드 레이아웃이 깨졌다. 현재 처한 상황은 내가 적용한 두 번째 슬라이드가 한 차례 밀린 현상이다. 이유를 몰라 구글링을 해봤더니 다음 두 가지 방법이 있었다.

  • observer , observerParents 옵션 추가

  • swiper 내부 상태 대신 swiper 인스턴스를 직접 사용하기

처음에 oberver 옵션을 사용했으나 해결되지 않았다. 결국 두 번째 방법으로 해결했다.

왜 observer 옵션이 안 먹혔을까?

swiper 내부에서 자체 상태 관리를 하고 있다. 리액트에서 setActiveIndex 와 같은 상태를 별도로 두고 swiper 내부 상태에 의존하면, 리사이징처럼 빠르게 업데이트가 일어나는 상황에서는 상태 간 동기화가 안맞을 때가 있다.

즉, 리액트에서 설정한 activeIndex와 swiper 내부의 실제 index 상태가 서로 달라질 수 있다는 이야기다. 그래서 observer 옵션을 써도, 리액트의 상태가 늦게 반영되면서 순간적인 화면 깨짐 현상이 발생했던 것이다.


swiper 인스턴스를 직접 쓰면 왜 해결되나?

swiper 내부 상태를 리액트 상태로 바꾸는 대신, swiper 가 직접 관리하는 인스턴스를 사용하는 방식으로 바꿔주었다.

onSlideChange={(swiper) => {
  const realIdx = swiper.realIndex;
  setActiveIndex(realIdx);
  bgSwiperRef.current?.slideToLoop(realIdx);
}}

이렇게 swiper 인스턴스에서 직접 현재 인덱스를 가져오면, 리액트 상태 업데이트의 지연 없이 즉시 swiper 의 실제 상태를 가져올 수 있다.

즉, swiper가 자체 관리하는 실제 슬라이드 상태에 직접 접근해서 화면이 깨지는 현상을 방지한 것이다.

(화질은 용량이슈로 인해...)



마무리


결론적으로, Swiper를 사용할 때는 swiper 인스턴스를 통해 실제 상태에 접근하는 게 더 안정적이다. 리액트의 상태를 별도로 관리하기보다는 swiper 가 자체 관리하는 상태를 직접 쓰는 방식을 기억하자.

이 간단한 팁 하나가 슬라이드 레이아웃이 무너지는 스트레스를 없애줬다.

profile
완전완전완전초보초보초보

0개의 댓글