모바일에서 보여줄 탭 또는 메뉴가 많을 때 스크롤 처리해서 보여줄 때가 많은데,
여기서 스크롤도 가능해야하고, 스크롤을 넘겨서 탭을 누르면 누른 탭으로 스크롤 위치가 이동되는 동작을 구현하고 싶었습니다.
구현 방법은 여러가지이긴 합니다.
직접 구현하거나 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>
Swiper slide 를 컨트롤 해야하기 때문에, swiper state를 만든 후, Swiper container 부분 (위 코드에선 TabListSwipe) 에 onSwiper={(swiper) => setSwiper(swiper)}
를 넣어서 Swiper를 정의해줍니다.
슬라이드 위치가 페이지 리로드가 되어도 유지 되어야하기 때문에 handleChangeSlide
함수를 만들어서 로컬스토리지에 탭 index를 저장합니다.
만든 함수를 SwiperSlide에 onClick으로 넣어줍니다.
useEffect
로 마운트 됬을 때, 슬라이드 위치가 로컬스토리지에 기록해둔 탭 index대로 이동되게 해줍니다.
매우 잘됩니다! 하나 아쉬운거라면, 클릭했을 때 슬라이드 위치가 0번에 있다가
갑자기 슉하고 이동되는 감이 있는데 이건 좀 고민해봐야겠습니다! 😊