프로젝트 KKu-Woon을 진행하며 유저 리스트를 carousel 형식으로 구현해야 상황이 있었습니다.
프로젝트 기간이 여유롭지 않고, 캐러셀은 라이브러리로 잘 만들어져 있기 때문에 오픈 소스를 사용하여 구현하기로 결정하였습니다.
고려한 라이브러리는 "react-slick" 과 "swiper" 두가지 라이브러리를 고려하였습니다. 그 중 swipe를 사용하여 해당 ui를 구현하였고 구현하면서 발생한 에러와 해결방법을 공유합니다.
✔ Swiper를 사용한 이유?
- 예전에 강좌를 들으면서 react-slick을 한번 사용해 보았고 새로운 라이브러리 사용 방법을 공부하고 싶었음
- react-slick 경우 @types 파일이 있었지만 js 기반으로 구현되어 있고 swiper는 typescript로 구현 되어있음
- swiper 가 github star, npm download 수가 더 많았음
결론 부터 말하자면 저렇게 navigator 바깥에 있는 ui는 그냥 react-slick을 쓰는 게 더 좋을지도 모르겠다.
swiper 같은 경우는 navigator가 캐러셀 안에 즉, swipe-wrapper 안에 들어있어서 css를 커스텀하는 방식으로는 화살표가 사라져 바깥으로 사라지는 이슈가 있었습니다.
✔ 해결방법?
- 해결 방법을 구글에 찾아 봤는데 여기서 고생을 한게 구글에 있는 대부분의 해결 방법이 swiper 6버전을 기준으로 작성되어있고 최신버전인 8버전에서는 정상적으로 동작 하지 않는 이슈가 있었음
- 버전을 낮추는 방법도 시도 했지만 swiper에서 낮은 버전의 api를 지원하지 않을 수 도 있다는 글을 보았음
- useRef를 사용해서 button에 ref를 달아서 조작하는 방법을 시도 했는데 typescript 환경에서 정상적으로 동작되지 않음 (ref가 null이라고 나오거나 type error 발생)
- 최종적으로 해결 방법을 찾은 곳은https://github.com/nolimits4web/swiper/issues/3855#issuecomment-1010689372
이 방법을 기반으로 Swiper에 state를 달아서 사용하는 방법으로 해결
✔ Code
import React, { useState } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import { SwiperWrapper, Wrapper } from './carousel.style';
import { userDummy } from 'dummy';
import CarouselItem from './carousel-item';
import { ReactComponent as RightArrow } from '@assets/icons/right-arrow.svg';
import { ReactComponent as LeftArrow } from '@assets/icons/left-arrow.svg';
const UserCarousel = () => {
const userData = userDummy;
const [swiper, setSwiper] = useState<any>();
const [reachingEnd, setReachingEnd] = useState<boolean>(false);
const [reachingFirst, setReachingFirst] = useState<boolean>(true);
return (
<Wrapper>
<h2>운동 현황보기</h2>
<SwiperWrapper>
<button onClick={() => swiper?.slidePrev()} disabled={reachingFirst}>
<LeftArrow stroke={reachingFirst ? '#D4D2D9' : '#6732FF'} />
</button>
<Swiper
slidesPerView={4}
slidesPerGroup={4}
onBeforeInit={swipper => setSwiper(swipper)}
onSlideChange={e => {
e.isEnd ? setReachingEnd(true) : setReachingEnd(false);
e.isBeginning ? setReachingFirst(true) : setReachingFirst(false);
}}
>
{userData.map(v => (
<SwiperSlide key={v.id}>
<CarouselItem nickname={v.nickname} url={v.imageUrl} />
</SwiperSlide>
))}
</Swiper>
<button onClick={() => swiper?.slideNext()} disabled={reachingEnd}>
<RightArrow stroke={reachingEnd ? '#D4D2D9' : '#6732FF'} />
</button>
</SwiperWrapper>
</Wrapper>
);
};
export default UserCarousel;
css code:
import styled from 'styled-components';
export const Wrapper = styled.section`
padding: 30px 0px 0px 0px;
& h2 {
margin-left: 20px;
font-weight: 700;
font-size: 18px;
}
`;
export const SwiperWrapper = styled.div`
position: absolute;
width: 100%;
margin-top: 12px;
display: flex;
& button {
background: transparent;
}
.swiper {
text-align: center;
}
`;
export const ItemWrapper = styled.div`
& img {
width: 50px;
height: 50px;
border-radius: 50%;
}
`;
해결해서 다행이지만 그냥 react-slick 쓸걸 그랬다. 공식문서를 확인해 보면 내가 구현하려는 ui는 react-slick에서 기본 제공하는 ui 와 더 유사한듯
https://react-slick.neostack.com/docs/example/pause-on-hover
라이브러리 사용하는 것도 무작정 갖다 쓰는게 아니라 구현하려는 ui와 구현 방법을 먼저 고려하고 선택해야 함을 배움
'react' 카테고리의 다른 글
Recoil은 쉬운 라이브러리?(Recoil vs Redux) (0) | 2022.09.05 |
---|---|
CSS-in-JS vs CSS-module vs Post CSS 차이 구분하기 (0) | 2022.09.02 |
Numble 챌린지 회고록 (0) | 2022.05.16 |
[React 상태관리] react-query 입문 하기 (0) | 2022.04.13 |
react 무한스크롤 구현하기(react-intersection-observer, createAsyncThunk 사용) (0) | 2022.04.07 |
댓글