Programming/React

[React] 이미지 슬라이더 만들기(자동, 무한반복)

dev seon 2024. 2. 1. 13:54

프로젝트에서 메인 페이지와 상세 페이지 상단에 이미지 슬라이더를 넣기로 했다.
조건은 두 가지.
1. 화살표 버튼을 눌렀을 때 이동이 가능할 것.
2. 시간이 지나면 자동으로 다음 이미지로 넘어갈 것.
 
<완성 이미지> - 옆으로 넘어가는 장면

<사용한 hook>
useState와 useEffect가 필요하다.

import { useState, useEffect } from 'react';

 
 
<사용한 외부 라이브러리>
react-icons를 설치하여 화살표 아이콘을 가져온다.

import { IoIosArrowForward, IoIosArrowBack } from 'react-icons/io';

 
이미지 슬라이드에 들어갈 이미지들은 배열 형태로 외부에서 props로 받아오도록 한다.

export default function ImageSlider({ slides })

 
우선 이미지 슬라이더에서 현재 보여줄 이미지가 무엇인지 매번 바뀌기 때문에
이미지 인덱스 값을 useState를 활용하여 바꾸도록 한다.
또 전체 이미지의 개수도 확인하여 변수로 저장한다.

const [current, setCurrent] = useState(0);
const length = slides.length;

 
다음은 화살표를 누르면 앞이나 뒤 슬라이드로 이동하는 함수를 만든다.
setCurrent를 활용하여 이미지 인덱스 값을 바꿔주는데,
이때 만약 마지막 페이지였을 경우 뒤로 넘길 때 첫 페이지로 이동하도록,
첫 페이지였을 경우 앞으로 넘길 때 마지막 페이지로 이동하도록 설정하여
슬라이더가 끝나지 않고 무한 반복되도록 한다.

const nextSlide = () => {
    setCurrent(current === length - 1 ? 0 : current + 1);
  };

  const prevSlide = () => {
    setCurrent(current === 0 ? length - 1 : current - 1);
  };

 
 
useEffect는 자동 슬라이드를 만들기 위해 필요하다.
인터벌을 5000으로 정해놓고 다음 슬라이드로 넘어가도록 한다.
만약 슬라이드가 없는 경우는 코드가 동작하지 않도록 예외처리를 해주었다.

useEffect(() => {
    const interval = setInterval(() => {
      nextSlide();
    }, 5000); 

    return () => clearInterval(interval); // 
  }, [current, length]);

  if (!Array.isArray(slides) || slides.length <= 0) {
    return null;
  }

 
마지막으로 앞서 선언한 함수들을 활용하여 화면에 이미지 슬라이드를 구현한다.
화살표를 누르면 앞뒤로 이동하도록 하고 슬라이드를 보여줄 때는 Map 함수를 활용한다.

return (
    <div className='imageSlider'>
      <IoIosArrowBack className='imageSlider-arrow left' size='30' onClick={prevSlide} />
      <IoIosArrowForward className='imageSlider-arrow right' size='30' onClick={nextSlide} />
      {slides.map((slide, index) => {
        return (
          <div
            className={index === current ? 'slide active' : 'slide'}
            key={index}
          >
            {index === current && <img src={slide.image} className='image' />}
          </div>
        );
      })}
    </div>
  );

 
 
마지막으로 scss를 활용하여 스타일을 적용해준다.
가장 상위에 overflow: hidden을 넣어 원하는 위치에서만 이미지 슬라이더가 넘어가는 것이 보이도록 한다.

.imageSlider {
  width: 600px;
  height: 300px;
  position: relative;
  overflow: hidden;
  margin-bottom: 20px;
  z-index: 1;

 
각각의 슬라이드에는 이미지가 넘어갈 때 자연스러운 애니메이션이 들어가도록 한다.
현재 이미지에 대해서는 추가 스타일을 설정하여 이미지 슬라이드를 완성한다.
 

.slide {
    display: flex;
    transition: transform 0.5s ease;
    &.active {
      transform: translateX(0);
    }
    &:not(.active) {
      transform: translateX(100%);
    }

 
+) 추가로 내가 만든 이미지 슬라이더 화살표 스타일을 공유한다.

  .imageSlider-arrow {
    position: absolute;
    top: 150px;
    background-color: rgba(141, 141, 141, 0.5);
    cursor: pointer;
    border-radius: 5px;
    transition: background-color 0.5s ease;
    z-index: 10;
    &.left {
      margin-left: 25px;
    }
    &.right {
      left: 550px;
      margin-right: 25px;
    }
  }