[React] 자동 슬라이드 구현 안내서 2부

흩날리는추억·2023년 9월 24일
0

들어가며

1부 내용입니다. React에서 이미지 슬라이드 구현 안내서 1부를 다녀오시길 바랍니다.

버튼 기능 구현

이미지 슬라이드에서 현재 표출되는 이미지의 이전 또는 다음 이미지를 표출ㅎ 하는 버튼을 만들겠습니다.

  • 이미지 슬라이드의 시작, 끝 번호와 이동할 때 필요한 1를 상수에 할당
  • 이전, 다음 버튼 생성
  • 버튼을 눌렀을 때 호출 할 moveToSlide에 함수 작성

moveToSlide의 경우 매개변수가 존재하는데 이전, 다음 버튼을 누를 경우 각각 'prev'와 'next'로 들어오게 됩니다. 이를 통해 눌려진 버튼이 무엇인지 판단하고, 그에 맞게 curSlide의 값을 변경합니다. 예를 들어 다음 버튼을 눌렀을 경우 현재 curSlide의 값이 마지막 이미지의 번호(LAST_SLIDE_INDEX - MOVE_SLIDE_INDEX)보다 작다면 1(MOVE_SLIDE_INDEX) 이동하게 됩니다.

const Slide = () => {
  const trainCompartment = ['1 칸', '2 칸', '3 칸', '4 칸', '5 칸'];

  const [curSlide, setCurSlide] = useState(0); // 이미지 슬라이드에서 표출되는 이미지 번호

  const FIRST_SLIDE_INDEX = 0; // 이미지 슬라이드의 시작 번호
  const LAST_SLIDE_INDEX = trainCompartment.length - 1; // 이미지 슬라이드의 끝 번호
  const MOVE_SLIDE_INDEX = 1; // 이미지 슬라이드 이동 값

  const moveToSlide = (value) => {
    if (value === 'next') {
      // 슬라이드 끝점에 도달했을 때 curSlide의 값을 바꿔 처음으로 돌아가게 한다.
      setCurSlide((prevState) =>
        prevState < LAST_SLIDE_INDEX
          ? prevState + MOVE_SLIDE_INDEX
          : FIRST_SLIDE_INDEX
      );
    }
    if (value === 'prev') {
      // 슬라이드 시작점에 도달했을 때 curSlide의 값을 바꿔 마지막으로 돌아가게 한다.
      setCurSlide((prevState) =>
        prevState > FIRST_SLIDE_INDEX
          ? prevState - MOVE_SLIDE_INDEX
          : LAST_SLIDE_INDEX
      );
    }
  };
  
  return (
    <div className='train'>
      <button
        className='prev-button'
        onClick={() => moveToSlide('prev')}
      >
        이전
      </button>
      <div className='show'>
        {
          trainCompartment.map((item, index) => (
            <div
              className='compartment'
              key={index}
              style={{
                // 현재 이미지 번호의 값을 넣어준다.
                transform: `translateX(${-1100 * curSlide}px)`,
                transition: 'all 0.4s ease-in-out',
              }}
            >
              {item}
            </div>
          ))
        }
      </div>
      <button
        className='next-button'
        onClick={() => moveToSlide('next')}
      >
        다음
      </button>
    </div>
  );
};

자동 슬라이드 기능 구현

버튼을 누르지 않아도 자동적으로 다음 이미지가 표출되는 기능을 구현하겠습니다.

  • setInterval를 사용하여 일정 시간이 지났을 경우 curSlide 값 변경

추가적으로 React에서 setInterval의 사용 방법이 JavaScript와는 다릅니다. 이와 관련된 내용을 알고 싶은 분들은
React에서 setInterval 사용하기 안내서로 가셔서 읽어보시길 추천합니다.

// Interval ID를 저장할 변수
  const [intervalId, setIntervalId] = useState(null);

  const autoMoveSlide = () => {
    if (intervalId !== null) {
      clearInterval(intervalId);
    }

    setIntervalId(
      setInterval(() => {
        setCurSlide((prevState) =>
          prevState < LAST_SLIDE_INDEX
            ? prevState + MOVE_SLIDE_INDEX
            : FIRST_SLIDE_INDEX
        );
      }, 3000)
    );
  };

  useEffect(() => {
    autoMoveSlide();

    return () => clearInterval(intervalId);
  }, []);

슬라이드의 현재 위치 표시 및 이동

현재 이미지가 슬라이드에서 어디에 위치하는지 사용자에게 보여주고, 사용자가 원하는 위치의 이미지를 볼 수 있도록 도와주는 기능을 구현하겠습니다.

  • trainCompartment 배열의 index를 이용하여 기능 구현
  • index를 눌렀을 때 호출 할 handlePaginationClick 함수 작성
// 동일 부분 제외
    const handlePaginationClick = (index) => {
      setCurSlide(index);
      autoMoveSlide(); // curSlide가 변경된 후 setInterval 대기 시간 초기화
    };

   return (
    <div className='train'>
      <button
        className='prev-button'
        onClick={() => moveToSlide('prev')}
      >
        이전
      </button>
      <div className='show'>
        {
          trainCompartment.map((item, index) => (
          <div
            className='compartment'
            key={index}
            style={{
              transform: `translateX(${-1100 * curSlide}px)`,
              transition: 'all 0.4s ease-in-out',
            }}
          >
            {item}
          </div>
          ))
        }
      </div>
      <ol className='slide-index'>
         {
          trainCompartment.map((_, index) => (
          <li
            key={index}
            className={`index-item ${curSlide === index ? 'active' : ''}`}
            onClick={() => handlePaginationClick(index)}
          >
            {index + 1}
          </li>
          ))
        }
      </ol>
      <button
        className='next-button'
        onClick={() => moveToSlide('next')}
      >
        다음
      </button>
    </div>
  );
};

아래의 css 코드는 원래 코드에서 추가만 해주시면 됩니다.

.slide-index {
  position: absolute;
  display: flex;
  gap: 8px;
  margin-top: 365px;
  cursor: pointer;
}

.index-item.active {
  color: blue; // 선택된 index 색 변경
}

마치며

이미지 슬라이드를 구현하기 전에 JavaScript로 원리 및 구현 방식을 학습한 뒤에 직접 React로 구현했습니다. 단순히 React에서 작동할 수 있을 정도로만 수정하면 간단하게 끝난다고 생각 했지만, 위에서 언급한 setInterval과 같이 React에서 사용할 때 추가적인 작업이 필요한 부분이 있었고, 이 글에 적진 않았지만 이미지 슬라이드를 구현하면서 useRef를 사용해야할 경우도 있었습니다. 이 밖에도 이미지 슬라이드를 구현하는데 사용되는 추가적인 기능들이 있었지만, 개인적으로 최소한의 기능들을 간단하게 만들고 싶었기 때문에 이런식으로 구현하게 되었습니다.

profile
걱정보다 생각을 하고 싶은 사람

0개의 댓글