[REACT] 이미지 슬라이드 구현하기

박희주·2022년 6월 29일
0

React로 이미지 슬라이드 구현해보기

1. 최초 계획

최초에는 이미지 슬라이드를 Carousel형태로 무한 루프를 돌릴 수 있게 만들고 싶어서 열심히 구글링을 통해 검색을 실시 하였으나 대부분의 구글에서의 검색 결과는 외부 라이브러리를 활용해 코드를 작성하는 것이였고 현재 프로젝트를 진행하면서 외부 라이브러리는 사용을 하지 못하기 때문에 어쩔 수 없이 하드코딩을 하는 방식으로 택했다.

2. 수정된 계획

하드코딩을 하는 방식을 택해 이 페이지에서 코드를 참조하여 작성을 했고 해당 페이지에서 사용하는 코드는 children을 활용해서 작성하는 코드여서 정확하게 감이 잡히진 않았었다.

import React, { useState } from "react";

export const CarouselItem = ({ children, width }) => {
  return(
    <div className="carouselItem" style={{ width: width }}>
      {children}
    </div>
  );
};

const Carousel = ({ children }) => {
  const [activeIndex, setActiveIndex] = useState(0);
  
  return (
    <div className="carousel">
      <div className="inner" style={{ transform: `translateX(-${activeIndex * 100}%)` }}>
        {React.Children.map(children, (child, index)) => {
          return React.cloneElement(child, { width: "100%" });
        })}
      </div>
    </div>
  );
};

위의 형식으로 코드를 작성하고 이를 렌더링 하는 Main.js페이지에 <Carousel />로 붙여넣고 실행을 해본 결과 이미지가 슬라이드형식으로 잘 나타나긴 했으나 코드를 이해하기에는 너무 부족했다.

2-1. Live Review

해당 코드를 어제 저녁에 멘토님과의 1대1 리뷰를 실시했는데 children을 사용하지 않고도 바로 데이터를 토대로 map을 시켜서 같은 결과를 도출해낼 수 있다는 얘기를 들었고 어떻게 해야하는지 조금은 알려주셨는데
위의 코드는 한 파일내에 컴포넌트도 두 개로 나뉘어 있어 좋은 방법은 아니라고 알려주심과 동시에 CarouselItem을 제거하고 Main.js에서 해당 아이템들을 렌더링 하는 <img />를 Carousel.js로 데려와서 데이터를 토대로 map을 직접 돌리는 방법이었다.

<div
  className="inner"
  style={{ transform: `translateX(-${activeIndex * 100}%)` }}
  >
    {carouselData.map(({ id, img, alt }) => {
      return (
        <div className="carouselItem" key={id}>
          <img alt={alt} src={img} />
        </div>
        );
      })}
</div>

이런 식으로 carouselData라는 state를 활용해 데이터를 담아 그 데이터를 토대로 바로 map을 돌리는 방법이었다.
일단 이 방법까지 리뷰를 받은 후에 혼자서 리팩토링을 들어갔다.

2-2. 리팩토링

children을 활용하지 않고 데이터를 활용해서 map을 돌릴 수 있다는 말을 토대로 목데이터를 최대한 적극 활용하기로 했다.
기존 코드를 참고로 목데이터를 활용해 리팩토링을 해나가기 시작했는데 처음에는 어떻게 굴려야 할지 몰라 헤메긴 했지만 데이터를 활용한다는 말을 떠올리며 아래와 같은 방법으로 해나가기 시작했다.

{carouselData.map((el, index) => {
  return (
    <button
      key={index}
      className={`choose${index === activeIndex ? ' active' : ''}`}
      onClick={() => {
        updateIndex(index);
      }}
    />
  );
})}

기존에 children으로 접근된 indicator버튼을 구현하는데 있어 children이 삭제되자 마자 오류를 뱉기 시작했으나 어차피 indicator버튼도 마찬가지로 같은 데이터를 사용하기 때문에 해당데이터를 토대로 같이 map을 돌리기 시작하니 정상적으로 작동을 했다.
또한 updateIndex라는 함수를 제작해 사진이 순서대로 넘어가고 끝 번호에서 다시 첫 번호로 돌아오게 하는 역할을 하게 했다.

const [activeindex, setActiveIndex] = useState(0);

const updateIndex = newIndex => {
  let count = carouselData.length;
  if (newIndex < 0) {
    newIndex = count - 1;
  } else if (newIndex >= count) {
    newIndex = 0;
  }

  setActiveIndex(newIndex);
};

해당 형태도 처음에는 React.child.count라는 children개념을 사용하다 해당 부분을 없앴을 때 이 부분은 어떻게 대체를 해야하나 하는 생각을 하고 있던 찰나에 count라는 역할을 하는 변수를 만들어서 그 변수를 데이터의 길이를 기준을 변수로 잡으면 되겠다라는 생각이 들어 바로 실행에 옮겨 보았다. 그래서 count = carouselData.length;를 담아 바로 사용해본 결과 이전에 children을 활용했을 때 처럼 정상적으로 indicator버튼도 렌더링이 되었다.

3. 결론

이번 Carousel기능을 해보면서 많이 아쉬웠던 점은 아무래도 사진이 한 방향으로 무한히 돌게끔하는 기능을 해보고 싶었으나 해당 기능은 추후 프로젝트 종료 후 개인적으로 연구해보고 구현해볼 예정이다.

profile
하나부터 열까지, 머리부터 발 끝까지

0개의 댓글