Joyful 개발

[React] 리액트에서 Swiper.js 를 사용해보자. Swiper 슬라이드 사용예제, Navigation의 arrow 버튼 커스텀하기

개발자 조이 2021. 9. 20. 22:24
728x90
반응형

스와이프 기능이 있는 슬라이드를 만들어야 할 때 유용한 Swiper 라이브러리를 리액트에서 사용하는 방법과 예제를 포스팅해보려고 한다

 

Swiper


Swiper.js는 스와이프 기능이 있는 슬라이드 UI를 제공하는 라이브러리이다.

https://swiperjs.com/

 

Swiper - The Most Modern Mobile Touch Slider

Swiper is the most modern free mobile touch slider with hardware accelerated transitions and amazing native behavior.

swiperjs.com

공식사이트의 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

 

⚠️ Swiper7: "Module not found: Can't resolve 'swiper/react' (vue/svelte/...)" · Issue #4871 · nolimits4web/swiper

If you have such issue with Swiper 7, it means your bundler/environment/framework/tooling doesn't support ESM packages. You should update your bundler/environment/framework/tooling or stay on S...

github.com

 

 

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 는 아주 편리하고 유용한 라이브러리다 !

 

 

 

혹시나 이 포스팅을 적용하다 중간에 틀린 부분이 있거나, 궁금한 부분이 있다면 언제든 댓글 남겨주세요 !

728x90
반응형