몽땅뚝딱 개발자

[React] Swiper 적용하기 (with. TypeScript, SCSS) 본문

Development/React.js · Next.js

[React] Swiper 적용하기 (with. TypeScript, SCSS)

레오나르도 다빈츠 2023. 3. 10. 18:12

 

 

 

 

React + Typescript 환경에서 Swiper 적용하기!

 

 


 
오늘도 안됐ㄷㅏ
이젠 개의치않아 맨날 안되니깐 말이야 !
 

 
 
 
 


 
 
 
 
내가 구현할 환경에서는 React, TypeScript, SCSS를 사용하고 있다.
 
 
1. Swiper를 설치해준다.
가장 최신버전으로 했다.

$ npm i swiper

 
 
 
2. 이렇게 선언해준다.
이렇게 선언하면 이미지 슬라이드까지는 구현이 된다.

<Swiper
  spaceBetween={50}
  slidesPerView={1}
>
  {
    displayImageList.map((url, index) => {
      return (
          <SwiperSlide className="slide-item" key={index}>
            <img src={url} />
          </SwiperSlide>
      )
    })
  }
</Swiper>

 

 
 
 
✍🏻 여기서 내가 원하는 바를 정리해보자면
1) 현재 슬라이드의 인덱스를 받아와서 화면에 노출해야한다.
2) 2개의 탭을 왔다갔다 하는 것이기 때문에 다른 탭을 누르면 activeIndex(현재 활성화 된 슬라이드의 인덱스)도 함께 초기화되어야한다. 즉, swiper 초기화가 필요하다.
3) 클릭 시 이전이나 다음 슬라이드로 이동할 수 있는 네비게이션이 필요했고, 내가 원하는 위치와 모양으로 스타일을 변경해야한다.
 
 
 
 
3. 내가 원하는 것을 구현해보자
1) 현재 인덱스를 받아와 화면에 노출하기
swiperCore.activeIndex를 사용하면 된다.

const [swiperIndex, setSwiperIndex] = useState(0);

// ...

<strong className="current-page">{swiperIndex + 1}</strong>
<Swiper
    ...,
    onActiveIndexChange={(swiperCore) => { setSwiperIndex(swiperCore.activeIndex) }}
/>

 
 
2) swiper 초기화하기

displayType이 현재 활성화 된 상단탭의 값이다.
onSwiper를 사용하여 SwiperCore를 바인딩해주고 useEffect로 displayType을 지켜보다가 변경이 되면 swipre.slideTo(0)로 초기화해준다.

const [swiper, setSwiper] = useState<SwiperCore>();

useEffect(() => {
  if (swiper) {
    swiper.slideTo(0); // 슬라이더 초기화
  }
}, [displayType]);

<Swiper
    ...,
    onSwiper={(swiper) => {
        setSwiper(swiper)
    }}
/>

 
 
 
3) 네비게이션 CSS 커스텀하기
이건 방법이 없어서 찾다 찾다가.. <Swiper>와 <SwiperSlide>에 id와 className을 주어 해결했다. 이미 기존에 먹는 css가 있기때문에 명시도를 가장 높게 해야한다. id와 class를 name을 적용하여 명시도를 높이면 웬만한 스타일은 다 줄 수 있다.
(명시도란? https://developer.mozilla.org/ko/docs/Web/CSS/Specificity) 

 

참고할 것은 이 CSS로 after를 none 처리 해주어야 한다. after를 사용한다면 커스텀하게 처리해주면 되겠지만 after로 처리할 것이 없다면 display: none을 해주자. 그렇지않으면 기존 화살표 이미지가 그대로 보인다.

.swiper-button-prev:after,
.swiper-button-next:after {
  display: none;
}

 
 
 
 
전체코드를 보면 이러하다.

import {useState} from "react";
import {EDisplayType} from "@/interface";
import { Swiper, SwiperSlide } from 'swiper/react';
import SwiperCore, { Navigation } from 'swiper';

SwiperCore.use([Navigation]);

export default function ImageSlider({
     beforeImageList,
     afterImageList,
   }: Props) {

  const [displayType, setDisplayType] = useState(EDisplayType.BEFORE);
  const [displayImageList, setDisplayImageList] = useState(beforeImageList);
  
  const [swiper, setSwiper] = useState<SwiperCore>();
  const [swiperIndex, setSwiperIndex] = useState(0);
  
  const handleChangeDisplayType = (displayType: EDisplayType) => {
    setDisplayType(displayType);
    setDisplayImageList(displayType === EDisplayType.AFTER ? afterImageList : beforeImageList);
  };
  
  useEffect(() => {
    if (swiper) {
      swiper.slideTo(0); // 슬라이더 초기화
    }
  }, [displayType]);

  return (
      <>
        <strong className="current-page">{swiperIndex + 1}</strong>
        <Swiper
            id="swiper"
            className="swiper"
            onSwiper={(swiper) => {
              setSwiper(swiper)
            }}
            spaceBetween={50}
            slidesPerView={1}
            navigation
            onActiveIndexChange={(swiperCore) => { setSwiperIndex(swiperCore.activeIndex) }}
        >
          {
            displayImageList.map((url, index) => {
              return (
                  <SwiperSlide className="slide-item" key={index}>
                    <img src={url} />
                  </SwiperSlide>
              )
            })
          }
        </Swiper>
      </>
  )
}

 
 
 
 


 
 
 
 
🧨 난관: module 내의 스타일을 못 찾고 Module not found: Can't resolve 'swiper/css' 등등의 에러가 발생했다.
시도 1. 버전을 낮추라는 글이 많아서 6.8.x대로 내리고 다시 import 해보았다. → 실패


시도 2. 아래처럼 다 조합해서 import 해보았다. → 실패

// 시도 1
import 'swiper/css';

// 시도 2
import 'swiper/swiper.min.css'
import 'swiper/modules/pagination/pagination.min.css'

// 시도 3
@import "~swiper/modules/navigation/navigation";
@import "~swiper/modules/pagination/pagination";

// 시도 4
import "swiper/scss"
import "swiper/scss/navigation"
import "swiper/scss/pagination"

// 기타 등등 각 단어 조합해서 다 해봄

 

시도 3. (해서는 안 될 것) 모듈에 있는 scss를 다 복붙해서 가져왔다. 나는 스와이퍼 옵션 중에 네비게이션만 쓰려고했던터라 몽땅 들고와도 많지가 않아서 시도할 마음을 먹을 수 있었다. CSS가 잘 적용되었지만.. 양심이 이건 아니라고 외쳐서 다시 원복..! → 실패


시도 4. 결국 CDN으로 가져왔다. → 성공 

<!-- index.html -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.css" />

 
 
 
 


 

개인적으로 공부한 내용을 정리하는 블로그로
잘못된 개념을 게시하지않도록 주의하고 있으나 오류가 있을 수 있습니다.
 

 

Comments