[TIL] 2024-04-02 Swiper slideTo()

H Kim·2024년 4월 2일
0

TIL

목록 보기
56/69
post-thumbnail

마찬가지로 모달입니다.
모달 이자식...

모달은 페이지에 들어갔을 때 사실 숨겨져서 안 보이고 있다 뿐이지 진짜로는 우리가 보이지 않는 곳에 렌더링 되어서 돌아가고 있는 상태이기 때문에 뭔가... init으로는 해결할 수 없는 문제들이 종종 발생한다. 이런 문제들을 해결하는 게 쉽지 않은 것 같다.

이미지를 등록하는 과정에서 사용자들에게 가이드를 주기 위해 가이드를 롤링팝업으로 작성중이다.
근데 가이드의 슬라이드가 여러 장이 있고 사용자가 한 번 가이드 모달을 열어서 끝까지 다 봄 -> 그리고 닫음 -> 그랬다가 다시 엶
이러면 맨 마지막에 사용자가 봤던 슬라이드에 머물러 있고 다시 처음으로 셋팅이 되지 않는 것이 문제였다.
그렇게까지 볼 사용자가 있을까? 싶지만...
사실 중간엔 야,,, 걍 봐라,,, 라고 하고 싶었다,,,
하지만 그럴 수 없겠쬬...

이것또한 선배들의 지혜로 해결할 수 있었습니다...
언제쯤 혼자 알아서 하는 어린이가 될 수 있을까요!


import React, { useState, useRef } from 'react';
import { RollingModal } from 'pages/StoreImage/style';
import { CloseButton } from 'components/Button/Button';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Navigation, Pagination } from 'swiper/modules';
import styled from 'styled-components';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';

interface RollingPopupProps {
  maskClosable?: boolean;
  open: boolean;
  onOk: () => void;
  onCancel: () => void;
}

interface TStyleSwiper {
  slideidx: number;
}

const StyleSwiper = styled(Swiper)<TStyleSwiper>`
  .swiper-button-prev,
  .swiper-button-next {
    color: #afb3b8;
  }
  .swiper-button-prev:after {
    visibility: ${({ slideidx }) => (slideidx === 0 ? 'hidden' : 'visible')};
    padding-left: 40px;
    font-size: 30px;
  }
  .swiper-button-next:after {
    visibility: ${({ slideidx }) => (slideidx === 1 ? 'hidden' : 'visible')};
    padding-right: 40px;
    font-size: 30px;
  }
  .swiper-pagination-bullet-active {
    background: #606366;
  }

  .swiper-button-prev .swiper-button-disabled {
    visibility: hidden;
  }
  .swiper-button-next .swiper-button-disabled {
    visibility: hidden;
  }
`;

const RegisterGuideRollingPopup = ({ maskClosable, open, onOk, onCancel }: RollingPopupProps) => {
  const swiper = useRef(null);
  const [slideIdx, setSlideIdx] = useState<number>(0);
  const handleSlideChange = (swiperInfo) => {
    setSlideIdx(swiperInfo.activeIndex);
  };

  const handleCloseModal = () => {
    // 닫히기 전에 아주 살짝 먼저 움직이는 게 보여서 타임아웃을 걸었다.
    setTimeout(() => {
      swiper?.current.swiper.slideTo(0);
    }, 500);
    onCancel();
  };

  return (
    <RollingModal
      maskClosable={maskClosable}
      open={open}
      onOk={onOk}
      onCancel={handleCloseModal}
      footer={[
        <CloseButton onClick={handleCloseModal} key="footer">
          닫기
        </CloseButton>
      ]}
    >
      <StyleSwiper
        modules={[Navigation, Pagination]}
        slideperview={1}
        navigation
        pagination={{ clickable: true }}
        onSlideChange={(swiperChange) => handleSlideChange(swiperChange)}
        slideidx={slideIdx}
// 여기다가 ref를 걸어줬다
        ref={swiper}
      >
        <SwiperSlide>
          <img src={Guide_01} alt="register-guide" />
        </SwiperSlide>
        <SwiperSlide>
          <img src={Guide_02} alt="register-guide" />
        </SwiperSlide>
      </StyleSwiper>
    </RollingModal>
  );
};

export default RegisterGuideRollingPopup;

Swiper 자체에 initialSlide 라는 속성도 있는데 이건 먹히지 않았다... 왜냐면 아까 위에서 말했듯 사실 모달은 처음에 페이지가 렌더링 될 때 안 보이는 곳에 렌더링 되어있는 상태이고 얘를 닫는다고 해서 이게 사라지는 게 아니라 그냥 "숨겨진" 상태이기 때문에 initialSlide의 케이스에는 해당되지 않는다.

그 다음으로는 swiper?.slideTo({가려고 하는 index})로 조작하려고 했는데... 어쩐지 되지 않았다... 왜...?(이유는 모름) 정확하게는 알 수 없지만 타겟팅이 제대로 안 되는 것 같다는 느낌적인 느낌으로 인해 useRef로 정확히 타겟팅을 해 보았다.

그리고 성공...

이런 간단한 기능에도 이런 복잡한(아님) 로직을 넣어야 한다니...
저는 그만 울어버리고 말앗읍니다...

0개의 댓글