[JS]React Hooks로 Carousel Slider 만들기

PEPPERMINT100·2020년 11월 5일
12

서론

캐러셀 슬라이더는 많은 웹의 홈페이지에서 더 나은 사용자 경험을 위해 자주 사용되는 방식입니다. 일반적으로 이미지를 옆으로 넘기며 정보를 확인할 수 있습니다. jQuery나 캐러셀 슬라이더용으로 만들어진 라이브러리를 사용한다면 간단히 구글링해서 복사 붙여넣기로도 가능하지만 사실 이 정도 애니메이션은 바닐라 자바스크립트로도 충분히 가능합니다. 이번엔 React 의 useState, useEffect, useRef 만을 이용하여 다른 라이브러리를 사용하지 않고 React Component의 특징을 살린 캐러셀 슬라이더를 만들어 보겠습니다.
###세팅
create-react-app을 통해 리액트 앱을 만들어줍니다. 스타일링에는 styled-components를 사용하기 때문에 styled-components도 설치해줍니다.

npx create-react-app react-carousel
cd react-carousel && npm install --save styled-components

이후엔 Slider의 요소가 될 Slide 컴포넌트를 만들어줍니다.

import React from "react";
import styled from "styled-components";
export default function Slide({ img }) {
  return (
      <IMG src={img} />
  );
}
const IMG = styled.img`
  width: 100%;
  height: 70vh;
`;

이미지 파일을 props로서 받고 보여줍니다.

import React, { useState, useEffect, useRef } from "react";
import Slide from "./Slide";
import styled from "styled-components";
import img1 from "./../img/1.jpg"; //자신이 원하는 이미지를 import 하세요.
import img2 from "./../img/2.jpg";
import img3 from "./../img/3.jpg";

Slider.js 파일을 생성하여 캐러셀에 들어갈 이미지들과 이미지를 담을 Slide 그리고 React Hooks를 가져옵니다. Slider.js 파일을 위부터 아래로 훑어 나가며 코드에 대한 간단한 설명을 하겠습니다.

const Container = styled.div`
  width: 60%;
  overflow: hidden; // 선을 넘어간 이미지들은 보이지 않도록 처리합니다.
`;
const Button = styled.button`
  all: unset;
  border: 1px solid coral;
  padding: 0.5em 2em;
  color: coral;
  border-radius: 10px;
  &:hover {
    transition: all 0.3s ease-in-out;
    background-color: coral;
    color: #fff;
  }
`;
const SliderContainer = styled.div`
  width: 100%;
  display: flex; //이미지들을 가로로 나열합니다.
`;

먼저 styled-components를 통해 만든 간단한 스타일링을 보겠습니다. 가장 아래 슬라이더 컨테이너를 flexbox 레이아웃으로 지정하여 이미지들을 가로로 나열합니다. 그리고 overflow:hidden으로 컨테이너를 넘어간 이미지들은 보이지 않도록 합니다.

const TOTAL_SLIDES = 2;
export default function Slider() {
  const [currentSlide, setCurrentSlide] = useState(0);
  const slideRef = useRef(null);
const nextSlide = () => {
    if (currentSlide >= TOTAL_SLIDES) { // 더 이상 넘어갈 슬라이드가 없으면 슬라이드를 초기화합니다.
      setCurrentSlide(0);
    } else {
      setCurrentSlide(currentSlide + 1);
    }
  };
  const prevSlide = () => {
    if (currentSlide === 0) {
      setCurrentSlide(TOTAL_SLIDES);
    } else {
      setCurrentSlide(currentSlide - 1);
    }
  };

전체 슬라이드의 개수를 지정해줍니다. 배열처럼 0부터 시작하여 총 3개의 이미지를 사용했으므로 TOTAL_SLIDES에 2를 줍니다.
그 후 useState를 통해 현재 어떤 슬라이드를 보여주고 있는지 정하고 nextSlide와 prevSlide를 통해 현재 보여주는 슬라이드를 정할 수 있도록 합니다. 그리고 useRef를 통해 Slider의 정보를 보여줄 수 있도록 합니다.

useEffect(() => {
    slideRef.current.style.transition = "all 0.5s ease-in-out";
    slideRef.current.style.transform = `translateX(-${currentSlide}00%)`; // 백틱을 사용하여 슬라이드로 이동하는 애니메이션을 만듭니다.
  }, [currentSlide]);
return (
    <Container>
      {currentSlide}
      <SliderContainer ref={slideRef}>
        <Slide img={img1} />
        <Slide img={img2} />
        <Slide img={img3} />
      </SliderContainer>
      <Button onClick={prevSlide}>Previous Slide</Button>
      <Button onClick={nextSlide}>Next Slide</Button>
    </Container>
  );
}

가장 중요한 부분입니다. useEffect를 통해 현재 어느 슬라이드를 보여주고 있는지 정합니다. 가로로 Slide들이 나열되어 있으므로 translateX를 통해 양옆으로 이미지의 위치를 조정하도록 합니다.

결론

리액트에도 캐러셀 슬라이더를 위한 많은 라이브러리가 있지만 리액트의 훅들을 활용하여 캐러셀 슬라이더를 만들어 보았습니다. 복잡한 애니메이션이 아닌 이상 왠만한 애니메이션은 추가 라이브러리 없이 충분히 구현이 가능합니다. 리액트도 그 라이브러리도 결국 자바스크립트니까요.

profile
기억하기 위해 혹은 잊어버리기 위해 글을 씁니다.

0개의 댓글