상세 컨텐츠

본문 제목

[React/Front] React에서 slider를 적용해보자

프론트 연구 노트

by bydawn25 2022. 3. 14. 09:46

본문

현재 나는 의뢰받은 작업 중 [코코스 영수학원] 홈페이지를 리뉴얼 중이다. php codeigniter를 사용하여 구축되어있던 프레임워크에서 react typescript로 리팩토링하고 결제기능 등 간단한 기능을 추가드릴예정이다.

 

슬라이더가 적용되는 메인페이지

그 중 아래와 같이 슬라이더가 적용되야 하는 부분이 있었다. 이것을 어떻게 구축했는지에 대하여 간단히 설명해 보겠다.(~ ̄▽ ̄)~

 

출처 : https://frontendresource.com/css-range-sliders/ https://smartslider.helpscoutdocs.com/article/1785-framework

웹상에서 슬라이더는 이렇게 오른쪽으로 미는 형태의 bar도 있고 오른쪽 사진처럼 toggle하는 형태도 있다. 하지만 오늘 내가 말하는 슬라이더는 맨 위 사진처럼 알아서 이미지가 슉슉 넘어가는 형태! Carousel이다.

 

 

 

1. React Material UI Carousel 설치하기

React의 가장 강력한 장점 중 하나는 바로 여러 라이브러리를 npm이나 yarn을 통해 사용할 수 있다는것!

 

한 교수님이 말씀하셨다. "Don't retinvent the wheel"이라고. 쇽쇽 쓸만한 라이브러리가 없는지 찾아보던중 [ React Material UI Carousel ] 을 발견하였다. 타입스크립트 전용 라이브러리이고 현재 버전은 3.2.0이다.

https://www.npmjs.com/package/react-material-ui-carousel

 

react-material-ui-carousel

A Generic, extendible Carousel UI component for React using Material UI. Latest version: 3.2.0, last published: a month ago. Start using react-material-ui-carousel in your project by running `npm i react-material-ui-carousel`. There are 45 other projects i

www.npmjs.com

 

해당 라이브러리는 material ui를 사용하고 있기 때문에 아래와 같은 순서로 설치를 진행해줘야 한다. 필자는 npm을 주로 사용하고 있기때문에 그 기준으로 설명하겠다.

# 먼저 material ui를 다운받는다. (이미 설치되어 있다면 할 필요 없다)
npm install @mui/material
npm install @mui/icons-material
npm install @mui/styles

#carousel를 다운받는다.
npm install react-material-ui-carousel --save

* 혹시 material ui를 다운받는데 문제가 있다면 mui 버전에 따라 위 명령어들이 약간 달라져야 할 수도 있다.

 

npm을 통해 설치하였다면 이제 사용 할 준비는 끝났다.

 

 

 

2. 사용하기

먼저 아래와 같이 import해주자

import Carousel from 'react-material-ui-carousel'
import { Paper, Button } from '@mui/material'

 

기본적인 사용법은 아래와 같다.

<Carousel>
 { 보여주고자 하는 내용 } # 이 부분에 넘겨 보여주고자 하는 내용을 구현하면 된다.
</Carousel>

 

이때 Carousel tag는 Page 태그를 기준으로 여러 내용을 넘겨 보여주게 된다. 간단히 예제를 작성하면 아래와 같이 되겠다.

<Carousel>
 <Paper> 1 </Paper>
 <Paper> 2 </Paper>
</Carousel>

 

나는 이미지를 연속해서 보여주고 싶었기 때문에 아래와 같이 구현했다. 반복되는 요소는 map function을 이용하는것이 깔끔하기 때문에 map을 사용하였다.

var items = [
            {
                imgAddress: "/img/1.png"
            },
            {
                imgAddress: "/img/2.png"
            },
            {
                imgAddress: "/img/3.png"
            }
        ];

<Carousel indicators={false}>
    {
        items.map(
            (item, i) =>
                <div style={{width: '100%', height: this.state.height}} >
                    <img src={item.imgAddress} style={{width: '100%', height: 'auto'}} />
                </div>
        )
    }
</Carousel>

 

이미지가 전체적으로 보이지 않는 모습

여기서 왜 backgroundImage나 img를 단독으로 쓰지 않았는지 의문이 들 수 있겠다. 바로 문제가 생겼기 때문이다 ^^ img태그만 사용했을때 처음 페이지를 열었을때 이미지가 꾸겨져서 나왔다!

아마 responsive한 구현을 위해 이미지 width를 100%로 설정해 놓는 편인데 그때 height를 auto로 해놓으면 편리하여 그렇게 해놓은 편인데 이게 뭔가 이 라이브러리랑 맞지 않는것 같았다. 그래서 이 문제를 해결하기 위하여 state를 활용하여 각각 브라우저의 길이가 변경될때마다 이미지의 높이를 조정해 주기로 했다.

 

정말 auto 하나면 되는데 이 오류때문에 저걸 구현해야 하니 짜증났다 ㅠㅠ

 

 

3. resonsive한 이미지 높이 조절을 위해 height 수동설정하기

state = { height: 0 };

 자 문제를 해결해보자. 높이를 저정해줄 state를 선언한다.

 

getMainDivHeight = () => {       
    const mainImageWidth = 1920;       
    const mainImageHeight = 900;       
    return Math.floor((window.innerWidth*mainImageHeight) / mainImageWidth);   
}

브라우저 크기가 변경될때마다 불러줄 높이 계산식이다. 코코스 영수학원의 메인 이미지 고정크기는 위와 같으므로 이 비율을 이용하여 높이를 계산해준다. 요 코드에서 사용된 함수들은 아래와 같다.

width 불러오기 =>  window.innerWidth

소수점 아래 버리기 => Math.floor

 

updateDimensions = () => {       
    this.setState({height:this.getMainDivHeight()});   
};

state를 업데이트 할 함수를 만들어준다.

 

componentDidMount(){       
    window.addEventListener('resize', this.updateDimensions);       
    this.updateDimensions(); #최초로 한번 실행하기
}

요겨를 addEventListner를 통해 브라우져가 "리사이징" 될때마다 실행될 수 있도록 만들어준다.

 

전체 코드는 아래와 같다.

state = { height: 0 }; #난 state선언할 때 이렇게 하는게 좋다 .. 별 이유는 없다

componentDidMount(){       
    window.addEventListener('resize', this.updateDimensions);       
    this.updateDimensions(); #최초로 한번 실행하기
}

updateDimensions = () => {       
    this.setState({height:this.getMainDivHeight()});   
};

getMainDivHeight = () => {       
    const mainImageWidth = 1920;       
    const mainImageHeight = 900;       
    return Math.floor((window.innerWidth*mainImageHeight) / mainImageWidth);   
}

 

 

 

4. Carousel의 기타 옵션들

 3번 까지 구현을 완료하였다면 문제 없이 돌아갈 것이다. 지금 내가 쓰고 있는 옵션은 indicator 로 아래 slider의 위치중 몇번째 이미지를 보여주고 있는지 알려주는 동그라미들로 필요없는것 같아 빼두었다.

이 라이브러리는 해당 옵션말고도 풍부한 옵션을 제공하고 있다.

navButtonsProps #슬라이더를 넘기는 버튼을 커스터 마이징 할 수 있다.
NextIcon #다음 슬라이더로 넘어가는 버튼을 다른 이미지로 교체할 수 있다.
IndicatorIcon #아래 나타나는 인디케이터를 커스터 마이징 할 수 있다.
autoPlay #사용자가 눌러야 슬라이더가 넘어가게 설정할 수 있다.

이것말고도 훨씬 더 많으니 자세한 커스터마이징이 필요하신 분들은 이 포스팅에 기재된 공식 웹사이트를 방문하길 권장드린다. 🙌

 

 

 

 

이렇게 React Typescript를 활용하여 슬라이더를 구현해보았다! 혹시라도 질문이 있으면 남겨주시고 다음에는 또 유익한 웹개발 포스팅으로 찾아오겠다. 안녕 ~

 

 

 

 

 

 

 

관련글 더보기