💻 Frontend
React Carousel 이용한 Carousel 만들기
개요
현재 소프트웨어 마에스트로에서 모도코(Modoco)라는 온라인 모각코 플랫폼을 개발중입니다. 메인 페이지에서는 모각코를 진행할 수 있는 방들이 있는데 상단에는 본인이 만든 방들이 먼저 보입니다. 디자인은 네이버의 웨일즈온 스터디를 참고하여 만들었습니다.
출처) 웨일즈온 스터디
라이브러리
라이브러리는 react-items-carousel를 이용하였습니다.
설치방법
npm install react-items-carousel yarn add react-items-carousel
사용방법은 공식사이트를 참고하시면 될것 같습니다.
코드
코드를 통해 자세히 설명드리겠습니다. 저는 React, typescript를 사용하였습니다.
RoomCards.tsx
export default function RoomCards({ openCreateRoom, }: { openCreateRoom: () => void; }) { const { isLoading, error, data } = useRooms(); // 현재 방에 대한 data 정보 가져오기 (react-query사용) const [activeItemIndex, setActiveItemIndex] = useState(0); const [numOfCards, setNumOfCards] = useState(4); const [gutter, setGutter] = useState(28); const resize = () => { // window 사이즈 변경되었을 때 실행되는 함수 const width = window.innerWidth; if (width < 300) { setNumOfCards(1); setGutter(0); } else if (width < 500) { setNumOfCards(2); } else if (width < 768) { setGutter(14); } else if (width < 1024) { setNumOfCards(2); } else if (width < 1300) { setNumOfCards(3); } else { setNumOfCards(4); } }; useEffect(() => { window.addEventListener('resize', resize); return () => { window.removeEventListener('resize', resize); }; }, []); const newMyData = filterMyData(data); // filterMyData는 내가 만든 방만 필터링해주는 커스텀 함수 const TRUE = true; return ( <Container> <Title>내가 만든 모도코</Title> <MyRoomContainer> <ItemsCarousel chevronWidth={50} gutter={gutter} numberOfCards={numOfCards} slidesToScroll={numOfCards} outsideChevron={TRUE} activeItemIndex={activeItemIndex} requestToChangeActive={(value) => setActiveItemIndex(value)} rightChevron={ <Button type="button"> <RightArrow /> </Button> } leftChevron={ <Button type="button"> <LeftArrow /> </Button> } > {isLoading // 데이터 불러오는 중일때 ? [...Array(3)].map((no, index) => ( <EmptyBlock key={Symbol(index).toString()} isMain={false} /> )) : newMyData.map((data) => { // 데이터 다 불러왔을 때 return ( <MyBlock key={data.itemId} data={data} /> ); })} <CreateRoom openCreateRoom={openCreateRoom} /> </ItemsCarousel> </MyRoomContainer> ... </Container> ); } ...
구현방법은 비교적 간단합니다.
ItemsCarousel
태그 안에 반복할 아이템들을 넣어주면 됩니다. 여기서 추가로 라이브러리 옵션들을 설정해주면 됩니다. 문서에 나와있는 것들 중 몇가지에 대해 소개하겠습니다.infiniteLoop
:boolean
default값은 false입니다. true로 설정할 경우 아래와 같이 컨텐츠가 반복되어 보여집니다.
저는 마지막 아이템이 방만들기로 보여져야 하므로 기본값(false)로 해주었습니다.
chevronWidth
:number
default값은 0입니다.
chevronWidth
는 오른쪽 화살표와 왼쪽 화살표(chevrons)의 width값을 의미합니다.gutter
:number
default값은 0입니다.
gutter
는 아이템 사이의 간격을 나타냅니다. 저는 반응형으로 만들어주었기 때문에 전체 크기에 따라 gutter
를 다르게 설정해주었습니다. 이를 위해 useState
, useEffect
훅을 사용하여 window의 resize
이벤트를 걸어주었습니다. 리턴 함수에는 해당 이벤트 리스너를 삭제해주었습니다. 이렇게하여 사용자의 화면 크기에 따라 보여지는 카드의 갯수가 달라집니다.disableSwipe
:boolean
default값은 false입니다.
disableSwipe
는 chevrons
말고 카드를 스와이핑했을 때에도 넘어가게 설정하는 것을 나타냅니다.alwaysShowChevrons
:boolean
default값은 false입니다.
alwaysShowChevrons
는 더이상 넘어갈 아이템이 없을 때에도 chevrons
가 보이게 설정하는 것입니다.numberOfCards
:number
default값은 3입니다.
numberOfCards
는 gutter
와 마찬가지로 반응형에 따라 다르게 설정해주었습니다. 같은 방식이기 때문에 추가 설명은 생략하겠습니다.slidesToScroll
:number
default값은 1입니다.
slidesToScroll
는 chevrons
로 몇개의 카드를 넘길것인지 설정해주는 것입니다. 저는 numberOfCards
와 같은 값으로 해주었습니다.outsideChevron
:boolean
default값은 false입니다.
outsideChevron
는 chevron
을 밖에 위치할 것인지 안에 위치할 것인지 선택하는 옵션입니다. 저는 디자인 시안대로 해주었기 때문에 true로 해주었습니다.- true일 경우
- false일 경우
showSlither
:boolean
default값은 false입니다. true로 해줄경우 아래와 같이 다음 아이템의 내용이 보이게 됩니다.
firstAndLastGutter
:boolean
default값은 false입니다. true로 해줄 경우 아래와 같이 맨 처음 아이템과 마지막 아이템의 gutter이 다른 아이탬의 2배 값을 가지게 됩니다.
activeItemIndex
:int
필수 입력값입니다. 처음 active되는 item의 index를 의미합니다. 가장 첫번째 아이템이 먼저 보이게 하길 원하므로 0으로 설정해주었습니다.
requestToChangeActive
:function
필수 입력값입니다. 현재 컴포넌트 상태에 따라
activeItemIndex
를 설정해주는 함수입니다.rightChevron
,leftChevron
:node
default값은 null입니다. 저는 위와 같은 왼쪽, 오른쪽 화살표 버튼으로 설정해주었습니다.
마무리
이렇게 하여 Carousel을 만들어보았습니다. 문서와 예시들이 잘 정리되어 있어서 다른 Carousel라이브러리보다 좀 더 간편하게 만들 수 있었던 것 같습니다😊