[React] Swiper로 scrollable tab 구현하기!

P1ush·2023년 7월 7일
0

React

목록 보기
10/10
post-thumbnail

구현하고싶은 것

모바일에서 보여줄 탭 또는 메뉴가 많을 때 스크롤 처리해서 보여줄 때가 많은데,
여기서 스크롤도 가능해야하고, 스크롤을 넘겨서 탭을 누르면 누른 탭으로 스크롤 위치가 이동되는 동작을 구현하고 싶었습니다.

구현 방법은 여러가지이긴 합니다.

직접 구현하거나 react-tabs-scrollable , react-scroll 와 같은 라이브러리들로도 충분히 구현이 가능한데 제 탭의 경우는 살짝 다른 경우였습니다.

탭은 보통 누르면 밑에 있는 콘텐츠만 바뀌는데, 제 경우는 라우터로 탭을 구현했기때문에
페이지 자체가 리로드되면서 스크롤 위치가 계속 초기화 되는 이슈가 있었습니다.

그래서 계속 찾아보다가 처음에 올렸던 던전앤파이터 모바일 홈페이지에서는 이 동작을 Swiper로 간단하게 구현했길래 삽질만 하다가 이렇게 해보기로 했습니다 !

코드

import { SwiperSlide } from 'swiper/react';

const params = {
  watchOverflow: true,
  slidesPerView: "auto",
  freeMode: true
}

위에서 SwiperSlide만 import 해주고, Swiper 옵션들을 정해줍니다.


//tab.style.js

export const TabListSwipe = styled(Swiper)`
    display: flex;
    overflow: hidden;
    width: 100%;

    .swiper-wrapper{
        display: flex;
    }

    .swiper-slide{
        width: auto;
        height: auto;
        background: transparent;

        &::before{
            display: none;
        }

        &.active{
            >a{
                color: var(--tabActiveColor);
                background-color: var(--tabActiveBg);
            }
        }

        >a{
            ${mixins.fc}
            ${mixins.font('nexonLv1Gothic', 'var(--tabText)')}
            padding: 0 21px;
            min-width: 110px;
            height: 50px;
            border-radius: 25px;
            font-size: ${({ theme }) => theme.fontSizes.f18};
            white-space: nowrap;
        }

        &.disabled > a{
            color: var(--disabledColor);
            ${mixins.disabled}
        }

        ${({ theme }) => theme.tablet`
            ${mixins.aic};
            >a{
                width: 90px;
                height: 40px;
                font-size: ${({ theme }) => theme.fontSizes.f14};
            }   
        `};
    }
`

style 파일에서 Swiper container가 될 부분 스타일을 정의해줍니다.
width가 넘치기 때문에 overflow: hidden은 필수로 넣어줍니다!



const [swiper, setSwiper] = useState();
const getTabActiveIndex = localStorage.getItem('tabActiveIndex');

const handleChangeSlide = (index) => {
	localStorage.setItem('tabActiveIndex', index);
}

useEffect(() => {
	if(swiper){
      swiper.slideTo(getTabActiveIndex);
    }
}, [swiper]);


 <SubTabstyled.TabListSwipe {...params} onSwiper={(swiper)=> setSwiper(swiper)}>
     {category.tabDataState === 'mode' &&
     	Object.keys(tabData.mode).map((item, index) => {
         return (
           <SwiperSlide key={index} onClick={()=> handleChangeSlide(index)} className={pageActiveState.mode === index ? 'active' : null}>
               <Link href={} as={}>...</Link>
           </SwiperSlide>
         )})
	}
 </SubTabstyled.TabListSwipe>
</SubTabstyled.TabListSwipe>
  1. Swiper slide 를 컨트롤 해야하기 때문에, swiper state를 만든 후, Swiper container 부분 (위 코드에선 TabListSwipe) 에 onSwiper={(swiper) => setSwiper(swiper)} 를 넣어서 Swiper를 정의해줍니다.

  2. 슬라이드 위치가 페이지 리로드가 되어도 유지 되어야하기 때문에 handleChangeSlide 함수를 만들어서 로컬스토리지에 탭 index를 저장합니다.

  3. 만든 함수를 SwiperSlide에 onClick으로 넣어줍니다.

  4. useEffect 로 마운트 됬을 때, 슬라이드 위치가 로컬스토리지에 기록해둔 탭 index대로 이동되게 해줍니다.


결과

매우 잘됩니다! 하나 아쉬운거라면, 클릭했을 때 슬라이드 위치가 0번에 있다가
갑자기 슉하고 이동되는 감이 있는데 이건 좀 고민해봐야겠습니다! 😊

0개의 댓글