일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- javascript
- JS console
- NonNullable
- Chart.js
- CSS
- returnType
- React Native
- 개발콘텐츠
- typescript
- 제네릭
- const 단언문
- react
- 타입스크립트
- 공통컴포넌트
- React.js
- 티스토리꾸미기
- vue.js
- 2022
- 레이아웃쪼개기
- 커스텀
- utilty type
- 리액트
- 누구나 자료구조와 알고리즘
- reactjs
- 폰트적용하기
- 성능최적화
- click and drag
- 반복줄이기
- 타입좁히기
- TSDoc
- Today
- Total
몽땅뚝딱 개발자
[React] Swiper 적용하기 (with. TypeScript, SCSS) 본문
[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" />
개인적으로 공부한 내용을 정리하는 블로그로
잘못된 개념을 게시하지않도록 주의하고 있으나 오류가 있을 수 있습니다.
'Development > React.js · Next.js' 카테고리의 다른 글
React Query 개념 정리 (1) | 2023.10.19 |
---|---|
CRA 세팅 시 기본 파일 정보 (0) | 2023.10.15 |
[React] 소소한 깨달음과 팁 정리 (with. TypeScript) (0) | 2023.03.07 |
[React] useMemo (0) | 2023.02.17 |
[React] 카카오맵 사용하기 With. 타입스크립트 - (3) 커스텀 마커 사용하기 (0) | 2023.02.16 |