React 에서 라이브러리 없이 이미지 슬라이드 구현하기
다이나믹 한 이미지 배열 사이즈를 슬라이드로 만들기
서버에서 이미지 URL 이 담긴 배열을 data 로 받아 이미지 슬라이드로 만드는 예제 입니다.
슬라이드를 만들기 위해서는 3개의 div 태그가 필요합니다.
<div className="swiper-container-main non-scroll">
<div className="swiper-inner">
<div className="item">
container main 이 전체를 감싸는 wrapper 이고 이미지 전체의 길이를 담당합니다.
wiper inner 태그는 하나의 이미지를 보여주는 구간 입니다.
.swiper-container-main {
// width: 300vw; 동적으로 구현할 것임
transition: transform 0.5s;
}
.swiper-inner {
width: 100vw;
display: flex;
}
.swiper-inner img {
width: 100%;
}
.non-scroll {
overflow: hidden;
}
css 는 다음과 같습니다.
전체를 감싸는 컨테이너에 width 옵션은 이미지 배열을 받아와 그 길이로 동적으로 구현할 것이기 때문에 적지 않았습니다.
swiper-inner 에서 display: flex 를 줘서 이미지 들을 가로로 길게 나열 한뒤 width 옵션을 100vw(뷰포트 100%) 꽉차게 만듭니다.
swiper inner 태그 안에 img 태그의 이미지를 100%로 꽉차게 만들고 non-scroll 의 클래스 이름이 담긴 태그의 가로 스크롤을 숨김 처리 했습니다.
const Templates = () => {
const swiperRef = useRef<HTMLDivElement>(null);
const [swiperCurrentPosition, setSwiperCurrentPosition] = useState(0);
const [loop, setLoop] = useState<any>();
const imageData = axios.get('~~~~'); // 데이터를 가져오는 부분 로직은 생략합니다.
useEffect(() => {
swiperRef.current.style.width = imageData?.data
? `${imageData.data.length}00vw`
: '0';
}, [imageData]);
useEffect(() => {
if (!imageData?.data) return;
const swiperLoop = setTimeout(() => {
setSwiperCurrentPosition(prev => {
if (prev < imageData.data.length - 1) {
return prev + 1;
} else return 0;
});
}, 3000);
setLoop(swiperLoop);
return clearTimeout(loop);
}, [
imageData?.data,
setSwiperCurrentPosition,
swiperCurrentPosition,
]);
useEffect(() => {
swiperRef.current.style.transform =
swiperCurrentPosition === 0
? `translate(000vw)`
: `translate(-${swiperCurrentPosition}00vw`;
}, [swiperCurrentPosition]);
...
하나 씩 살펴보겠습니다.
...
const swiperRef = useRef<HTMLDivElement>(null);
...
<div ref={swiperRef} className="swiper-container-main">
swiper 컨테이너에 접근하기 위해서 ref 를 만들고 주입합니다 이렇게 한 이유는 style 값을 핸들링 하기 위해서 입니다.
useEffect(() => {
swiperRef.current.style.width = imageData?.data
? `${recommendResponse.data.length}00vw`
: '0';
}, [recommendResponse]);
imageData 의 데이터가 있으면 컨테이너 뷰포트 전체의 길이를 그 길이 만큼 잡고 없다면 0 으로 잡습니다.
const [swiperCurrentPosition, setSwiperCurrentPosition] = useState(0);
const [loop, setLoop] = useState<any>(null);
useEffect(() => {
if (!imageData?.data) {
clearTimeout(loop);
} else {
const swiperLoop = setTimeout(() => {
setSwiperCurrentPosition(prev => {
if (prev < imageData.data.length - 1) {
return prev + 1;
} else return 0;
});
}, 3000);
setLoop(swiperLoop);
}
return clearTimeout(loop);
}, [
imageData?.data,
setSwiperCurrentPosition,
swiperCurrentPosition,
]);
스와이퍼의 현재 위치 상태값을 담을 변수와 setTimeout 을 clear 해주기 위해서 useState 로 두개의 상태 관리 변수를 선언 합니다.
imageData 의 data 가 없다면
Timeout 을 클리어 하고 데이터가 있다면 그길이만큼 3초에 한번씩 다음 포지션 으로 넘어가는 루프를 만듭니다.
<div className="non-scroll">
<div ref={swiperRef} className="swiper-container-main">
<div className="swiper-inner">
{imageData?.data &&
imageData.data.map((item: imageDataInterface) => (
<SlideItem
key={item.htmlTemplateId}
imageURL={item.previewImagePath}
templateTitle={item.categoryName}
templateCategory={item.name}
/>
))}
</div>
</div>
</div>
이미지 슬라이드 가 완성되었습니다.
이것을 잘 활용하신다면 버튼으로 이미지 넘기기 마우스로 이미지 넘기기 등등.. 구현 하실수 있습니다.
'React' 카테고리의 다른 글
Typescript + Next.js 에서 Test 환경 설정하기 (0) | 2021.12.04 |
---|---|
Firebase 로 소셜로그인 연동하기 (2) | 2021.08.15 |
React 로 Youtube api 연동하기 (0) | 2021.08.14 |
React 에서 서버 없이 인스타그램 API 연동하고 피드 가져오기 (3) | 2021.08.08 |
React 주요 명령어 알아보기 (0) | 2021.07.19 |
댓글
이 글 공유하기
다른 글
-
Typescript + Next.js 에서 Test 환경 설정하기
Typescript + Next.js 에서 Test 환경 설정하기
2021.12.04 -
Firebase 로 소셜로그인 연동하기
Firebase 로 소셜로그인 연동하기
2021.08.15 -
React 로 Youtube api 연동하기
React 로 Youtube api 연동하기
2021.08.14 -
React 에서 서버 없이 인스타그램 API 연동하고 피드 가져오기
React 에서 서버 없이 인스타그램 API 연동하고 피드 가져오기
2021.08.08