스와이프 기능이 있는 슬라이드를 만들어야 할 때 유용한 Swiper 라이브러리를 리액트에서 사용하는 방법과 예제를 포스팅해보려고 한다
Swiper
Swiper.js는 스와이프 기능이 있는 슬라이드 UI를 제공하는 라이브러리이다.
공식사이트의 Demos 에서 다양한 형태의 슬라이드를 확인할 수 있고 이 중에서 필요한 슬라이드를 선택해서 적용하면 되는데, 이번 포스팅에서는 Navigation 슬라이드를 적용하는 법을 설명하려고 한다
설치
npm install swiper@6.8.4
Swiper는 최신 버전이 7버전이지만 이번 포스팅에서는 6.8.4 버전을 설치한다.
현재 프로젝트는 CRA로 개발환경을 설정했는데, 최신 버전을 설치했을 때 swiper 모듈을 찾을 수 없는 에러가 나타났다.
찾아보니 ESM packages를 번들러가 지원하지 않아서 생기는 문제였는데 혹시나 위와 같은 에러가 나타난다면 최신버전이 아닌 이전 버전인 6버전으로 낮춰서 설치하면 된다.
https://github.com/nolimits4web/swiper/issues/4871
Swiper 모듈 불러오기
// swiper
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/swiper.min.css";
import "swiper/components/navigation/navigation.min.css";
import SwiperCore, { Navigation } from "swiper";
최신버전이 아닌 이전 버전을 설치했다면 또 다시 주의해야할 부분이 있는데 css파일 import 부분이다.
최신버전은 "swiper/swiper.css" "swiper/components/navigation/navigation.css"으로 import 하지만, 이전 버전은 꼭 min.css로 import 해야한다. 그렇지 않으면 또 다시 css를 찾을 수 없다는 오류가 나온다 ^^..
그러니 꼭 위와 같이 min 이 붙은 css 파일을 import 해줘야 한다 !
Navigation 슬라이드를 만들어보자
// swiper
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/swiper.min.css";
import "swiper/components/navigation/navigation.min.css";
import SwiperCore, { Navigation } from "swiper";
const Showcase = () => {
SwiperCore.use([Navigation]);
return (
<Swiper>
<SwiperSlide>1</SwiperSlide>
<SwiperSlide>2</SwiperSlide>
<SwiperSlide>3</SwiperSlide>
</Swiper>
)
}
export default Showcase;
import한 Swiper가 슬라이드가 되고, SwiperSlide는 슬라이드 아이템이 된다.
SwiperCore.use를 이용해 Navigation을 넣어 Navigation을 사용할 것을 알린다.
여기까지만 해도 슬라이드가 완성된다.
슬라이드의 style 수정하기
// swiper
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/swiper.min.css";
import "swiper/components/navigation/navigation.min.css";
import SwiperCore, { Navigation } from "swiper";
const Showcase = () => {
SwiperCore.use([Navigation]);
const swiperStyle = {
position: "relative",
width: "752px",
height: "752px",
};
return (
<Swiper style={swiperStyle}>
<SwiperSlide>1</SwiperSlide>
<SwiperSlide>2</SwiperSlide>
<SwiperSlide>3</SwiperSlide>
</Swiper>
)
}
export default Showcase;
위와 같이 스타일객체를 만들어 Swiper 컴포넌트에 주입해주면 된다.
혹시나 styled-components를 사용하고 있다면?
// swiper
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/swiper.min.css";
import "swiper/components/navigation/navigation.min.css";
import SwiperCore, { Navigation } from "swiper";
const Showcase = () => {
SwiperCore.use([Navigation]);
return (
<StyledSwiper>
<SwiperSlide>1</SwiperSlide>
<SwiperSlide>2</SwiperSlide>
<SwiperSlide>3</SwiperSlide>
</StyledSwiper>
)
}
export default Showcase;
const StyledSwiper = styled(Swiper)`
position: relative;
width: 752px;
height: 752px;
`;
이렇게 styled 된 Swiper 컴포넌트를 만들어 적용할 수도 있다.
허허 역시 styled-components 너무 간편하고 좋다 !
이제 스와이프 될 때의 이벤트 등록과, 스와이퍼 객체를 이용해 슬라이드를 이동시키는 등의 로직을 추가해보자
Swiper 매개변수 전달하기
// swiper
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/swiper.min.css";
import "swiper/components/navigation/navigation.min.css";
import SwiperCore, { Navigation } from "swiper";
const Showcase = () => {
const [swiper, setSwiper] = useState(null);
SwiperCore.use([Navigation]);
const swiperParams = {
navigation : true,
onSwiper : setSwiper,
}
return (
<Swiper {...swiperParams} ref={setSwiper}>
<SwiperSlide>1</SwiperSlide>
<SwiperSlide>2</SwiperSlide>
<SwiperSlide>3</SwiperSlide>
</Swiper>
)
}
export default Showcase;
Swiper 슬라이드의 기능을 사용하기 위해 Swiper 컴포넌트 ref에 useState를 이용해 만든 setSwiper를 추가한다.
그리고 매개변수의 onSwiper에 setSwiper를 등록해주면,
이제부터 useState에 등록된 swiper를 이용해 swiper.slideTo( )와 같은 메서드를 사용할 수 있다.
swiper로 사용할 수 있는 메서드는 여기에서 확인할 수 있다.
// swiper
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/swiper.min.css";
import "swiper/components/navigation/navigation.min.css";
import SwiperCore, { Navigation } from "swiper";
const Showcase = () => {
const [swiper, setSwiper] = useState(null);
const [mainImageIndex, setMainImageIndex] = useState(0);
SwiperCore.use([Navigation]);
const swiperParams = {
navigation : true,
onSwiper : setSwiper,
onSlideChange: (e) => setMainImageIndex(e.activeIndex),
}
return (
<Swiper {...swiperParams} ref={setSwiper}>
<SwiperSlide>1</SwiperSlide>
<SwiperSlide>2</SwiperSlide>
<SwiperSlide>3</SwiperSlide>
</Swiper>
)
}
export default Showcase;
매개변수 중 onSlideChange의 이벤트 핸들러에 등록한 로직은 slide가 이동할 때 발생하는 이벤트로 나는 이 때 현재 어떤 슬라이드가 메인에 나와있는지 index값을 저장하는 용도로 사용했다.
이벤트 핸들러의 이벤트를 받아 console.log로 찍어보면 어떤 값들을 사용할 수 있는지 알 수 있다.
여기서 필요한 걸 찾아서 사용하면 되는데, 나는 e.activeIndex 값을 mainImageIndex 값에 저장한다.
swiper에서 사용할 수 있는 이벤트 종류는 여기에서 확인할 수 있다.
Navigation의 arrow 버튼을 커스텀 해보자
// swiper
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/swiper.min.css";
import "swiper/components/navigation/navigation.min.css";
import SwiperCore, { Navigation } from "swiper";
const Showcase = () => {
const [swiper, setSwiper] = useState(null);
const [mainImageIndex, setMainImageIndex] = useState(0);
SwiperCore.use([Navigation]);
const navigationPrevRef = useRef(null);
const navigationNextRef = useRef(null);
const swiperParams = {
navigation : true,
onSwiper : setSwiper,
onSlideChange: (e) => setMainImageIndex(e.activeIndex),
}
return (
<Swiper {...swiperParams} ref={setSwiper}>
<SwiperSlide>1</SwiperSlide>
<SwiperSlide>2</SwiperSlide>
<SwiperSlide>3</SwiperSlide>
<PrevButton ref={navigationPrevRef}>
<img alt="prevButton" src={prevIcon} />
</PrevButton>
<NextButton ref={navigationNextRef}>
<img alt="nextButton" src={nextIcon} />
</NextButton>
</Swiper>
)
}
export default Showcase;
우선 버튼으로 사용할 컴포넌트를 만들어준다. 스타일은 각자 알아서 필요한 모양으로 해준다.
그리고 useRef를 이용해 각 버튼 컴포넌트의 ref값을 만들어준다.
// swiper
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/swiper.min.css";
import "swiper/components/navigation/navigation.min.css";
import SwiperCore, { Navigation } from "swiper";
const Showcase = () => {
const [swiper, setSwiper] = useState(null);
const [mainImageIndex, setMainImageIndex] = useState(0);
SwiperCore.use([Navigation]);
const navigationPrevRef = useRef(null);
const navigationNextRef = useRef(null);
const swiperParams = {
navigation: { prevEl: navigationPrevRef.current, nextEl: navigationNextRef.current },
onBeforeInit: (swiper) => {
swiper.params.navigation.prevEl = navigationPrevRef.current;
swiper.params.navigation.nextEl = navigationNextRef.current;
swiper.activeIndex = mainImageIndex;
swiper.navigation.update();
},
onSwiper: setSwiper,
onSlideChange: (e) => setMainImageIndex(e.activeIndex),
};
return (
<Swiper {...swiperParams} ref={setSwiper}>
<SwiperSlide>1</SwiperSlide>
<SwiperSlide>2</SwiperSlide>
<SwiperSlide>3</SwiperSlide>
<PrevButton ref={navigationPrevRef}>
<img alt="prevButton" src={prevIcon} />
</PrevButton>
<NextButton ref={navigationNextRef}>
<img alt="nextButton" src={nextIcon} />
</NextButton>
</Swiper>
)
}
export default Showcase;
Swiper 매개변수의 navigation에 각 커스텀 버튼 엘리먼트를 등록하고, onBeforeInit 이벤트에도 위 코드와 같이 만들어둔 커스텀 버튼을 등록해준다.
onBeforeInit 에서 버튼을 등록해주지 않으면 기본 버튼과 커스텀한 버튼이 함께 나오는 문제가 발생하므로, navigation에 버튼을 등록했다고 하더라도 onBeforeInit에도 버튼을 꼭 등록해줘야 햔다.
이렇게 하면 커스텀한 버튼이 슬라이더의 버튼으로 바뀌게 된다 !
마무리
공식홈페이지만 참고해도 충분히 만들 수 있겠지만, 구현 중간 과정에서 에러도 발생하고 헷갈리는 부분도 있었기 때문에, 쉽게 정리된 글이 필요할 것 같아 적용과정을 한번 정리해서 적어보았다.
이 글엔 Navigation 형태의 슬라이드만 적혀있지만 다른 형태 적용도 이것과 크게 다를 것 같지는 않다.
스와이프 기능이 있는 슬라이드를 사용할 때 Swiper.js 는 아주 편리하고 유용한 라이브러리다 !
혹시나 이 포스팅을 적용하다 중간에 틀린 부분이 있거나, 궁금한 부분이 있다면 언제든 댓글 남겨주세요 !