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

해준박·2024년 3월 31일
0

구현내용

위 처럼 이미지와 버튼 컴포넌트2개를 추가하였고, prev, next로 이전 이미지와 다음 이미지를 보여줄 수 있도록 구현하였다.

코드

작년쯤 노마드코더에서 배웠던 기억이 있어서 강의를 다시 찾아보았다. 추가로 motion을 넣을 수 있는 라이브러리가 있었지만 따로 사용하지 않았다. 오직 다음이미지, 이전이미지

function Image({ images }: ImageType) {
  const [visibel, setVisibel] = useState(0);

  const onClickNextImage = () =>
    setVisibel((prev) =>
      prev === images.length - 1 ? images.length - 1 : prev + 1,
    );

  const onClickPrevImage = () =>
    setVisibel((prev) => (prev === 0 ? 0 : prev - 1));

  return (
    <ImageContainer>
      <MdOutlineArrowBackIosNew onClick={onClickPrevImage} size={30} />
      {images.map((image, idx) =>
        idx === visibel ? <ImageWrapper key={image} src={image} /> : null,
      )}
      <MdOutlineArrowForwardIos onClick={onClickNextImage} size={30} />
    </ImageContainer>
  );
}

코드 설명

이미지는 배열형태다
ex) images = ["이미지링크1","이미지링크2",....]

1. map() + 삼항연산자

const [visibel, setVisibel] = useState(0);

{images.map((image, idx) =>
        idx === visibel ? <ImageWrapper key={image} src={image} /> : null,
)}	

mpa() + 삼항연산자를 이용하였다.

처음 렌더링이 일어날 때, images의 idx(인덱스)와 visibel의값과 같을 경우 해당 인덱스의 image를 src로 값을 설정해주고 반환한다.

2. 이전페이지 다음페이지

const onClickNextImage = () =>
    setVisibel((prev) =>
      prev === images.length - 1 ? images.length - 1 : prev + 1,
    );

const onClickPrevImage = () =>
    setVisibel((prev) => (prev === 0 ? 0 : prev - 1));

 <MdOutlineArrowBackIosNew onClick={onClickPrevImage} size={30} />
      {images.map((image, idx) =>
        idx === visibel ? <ImageWrapper key={image} src={image} /> : null,
      )}
<MdOutlineArrowForwardIos onClick={onClickNextImage} size={30} />
  1. setVisible에서 삼항연산자를 이용하여 현재 값이 마지막 이미지 또는 첫번째 이미지 일 경우를 제외 하고는 visible값을 더하거나 빼준다.

  2. state가 변경 될 경우 map()이 다시 실행되며 <ImageWrapper />는 리렌더링이 일어나면서 다음 사진, 이전 사진을 보여준다.

결과

첫번째사진이나 마지막사진에서 각각 이전버튼 다음버튼을 누를 경우 더 이상 넘어가지 않게 구현이되었다.

추가로, 애니메이션을 추가하려면 react motion framer을 사용하면 편하게 할 수 있는듯, 물론 그냥 라이브러리 사용해도 가능한듯?

[ProductDetail] 상품 상세정보 레이아웃 작업 완료 + 이미지 슬라이드 구현(애니메이션 X) #10

profile
기록하기

0개의 댓글