[ React ] React-Slick 라이브러리 커스텀하기

시훈·2023년 11월 22일
1

라이브러리

목록 보기
1/2
post-thumbnail

0. React-Slick이란?

React-Slick은 슬라이더 기능을 간편하게 사용할 수 있는 라이브러리 입니다.
React-Slick 공식문서

1. React-Slick 설치하기

라이브러리:
npm install react-slick --save

CSS 및 기본 파일:
npm install slick-carousel --save

import "slick-carousel/slick/slick.css"; 
import "slick-carousel/slick/slick-theme.css";

두 개를 모두 설치해준 뒤, 슬라이더를 사용하는 위치에서 위의 css파일을 import해줍니다.

2. React-Slick 샘플 코드

공식문서에서 제공하는 샘플 코드입니다. 이 샘플 외에도 여러가지가 존재하니, 마음에 드는 것을 사용하시면 됩니다.

simpleSlider.js

import React from "react";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css"; 
import "slick-carousel/slick/slick-theme.css";

export default function SimpleSlider() {
  var settings = {
    dots: true,
    infinite: true,
    speed: 500,
    slidesToShow: 1,
    slidesToScroll: 1,
  };
  return (
    <Slider {...settings}>
      <div>
        <h3>1</h3>
      </div>
      <div>
        <h3>2</h3>
      </div>
      <div>
        <h3>3</h3>
      </div>
      <div>
        <h3>4</h3>
      </div>
      <div>
        <h3>5</h3>
      </div>
      <div>
        <h3>6</h3>
      </div>
    </Slider>
  );
}

결과화면


샘플 코드를 빌드하면 나타나는 첫 화면입니다. 아직 아무것도 없는 이 슬라이더를 하나하나 커스텀 해 보겠습니다.

(저는 알아보기 쉽게 하기 위하여 배경색 변경, 슬라이더 border, 양옆 margin을 해주었습니다)


3. settings 커스텀

const settings = {
      dots: true,
      infinite: true,
      speed: 500,
      slidesToShow: 1,
      slidesToScroll: 1
    };

샘플 코드에서 주어진 settings 입니다. 이곳에서 1차적으로 슬라이더의 커스텀이 가능합니다.

  • dot: true
    슬라이더 하단에 작은 점의 유무를 결정합니다.

  • infinite: true
    슬라이더의 마지막 콘텐츠와 맨 처음 콘텐츠를 연결할 것인지 결정합니다.

  • speed: 500
    콘텐츠의 전환 속도를 결정합니다. 값이 작아질수록 속도가 빨라집니다.

  • slidesToShow: 1
    열의 개수를 지정합니다.

  • slidesToScroll: 1
    한번에 넘어가는 콘텐츠의 개수를 지정합니다. slidesToShowslidesToScroll를 모두 3으로 지정한 결과입니다.

이 외에도 settings에서 커스텀이 가능한 유용한 기능들이 많이 있습니다. 공식문서에서 모든 기능들을 찾아볼 수 있습니다. 다음은 제가 유용하게 사용한 기능들 입니다.

  • rows: 3
    행의 개수를 지정합니다.
    타입: int

  • arrows: true
    좌우의 화살표 버튼의 유무를 결정합니다.

  • autoplay: true
    콘텐츠가 일정 시간마다 자동으로 넘어갑니다.

  • draggable: false
    슬라이더를 드래그로 넘길 수 없습니다.

  • fade: true
    콘텐츠가 서서히 바뀝니다.

  • vertical: true
    콘텐츠가 수직으로 이동합니다.

4. css 커스텀 with styled-components

4-1. 화살표 이미지 변경

원하는 이미지로 좌우 화살표를 변경하려면 먼저 기존 화살표를 없애야합니다.
저는 styled-components를 사용하여 기존에 있던 라이브러리 css를 오버라이딩 해주었습니다.

simpleSlider.js

...
return(
 <SliderContainer>
        <Slider {...settings}>
          <div>
            <h3>1</h3>
          </div>
          <div>
            <h3>2</h3>
          </div>
          <div>
            <h3>3</h3>
          </div>
          <div>
            <h3>4</h3>
          </div>
          <div>
            <h3>5</h3>
          </div>
          <div>
            <h3>6</h3>
          </div>
        </Slider>
      </SliderContainer>
)

style.js

export const SliderContainer = styled.div`
    margin: 0px 200px;
    border: solid 1px black;
    .slick-prev:before,
    .slick-next:before {
        display: none;	
    }
`

슬라이더의 부모 컴포넌트에 이렇게 작성해주시면 기존의 화살표가 사라집니다.
이제 settings에서 새로운 화살표를 추가할 준비가 되었습니다!

simpleSlider.js

...
//경고 방지를 위해 추가
const SlickButtonFix = ({ currentSlide, slideCount, children, ...props }) =>(
	  <span {...props}>{children}</span>
	);

const settings = {
      dots: true,
      infinite: true,
      speed: 500,
      slidesToShow: 1,
      slidesToScroll: 1,
      nextArrow: (			//오른쪽 화살표
        <SlickButtonFix>
          <NextTo />
        </SlickButtonFix>
      ),
  	  prevArrow: (			//왼쪽 화살표
        <SlickButtonFix>
          <Prev />
        </SlickButtonFix>
      )
    };

...

style.js

import styled from 'styled-components';
import arrow from './images/right.png'

export const NextTo = styled.div`
    background-image: url(${arrow});
    background-size: contain;
    height: 20px;
    width: 20px;
`

export const Prev = styled.div`
    transform: rotate(180deg);
    background-image: url(${arrow});
    background-size: contain;
    height: 20px;
    width: 20px;
`

이때 SlickButtonFix로 화살표 이미지를 감싸지 않으면 경고가 발생하게 됩니다. 해결을 위해 참고한 글
(콘솔창에 경고 발생)


결과 화면

양옆의 화살표가 원하는 이미지로 바뀌었습니다.


4-2. 슬라이더 양 옆의 컨텐츠 슬쩍 보여주기

요즘 웹사이트에서 많이 보이는 형태의 슬라이더 입니다. React-Slickstyled-components 라이브러리를 이용해 간단하게 구현해 보겠습니다.


먼저, 슬라이더 안에 들어갈 컨텐츠와 색상이 담긴 배열을 만들어 주었습니다.

simpleSlider.js

const list = [
    {
      content: 1,
      color: '#FF5757',
    },
    {
      content: 2,
      color: '#FFBC57',
    },
    {
      content: 3,
      color: '#FFEE57',
    },
    {
      content: 4,
      color: '#57FF86',
    },
    {
      content: 5,
      color: '#5786FF',
    },
    {
      content: 6,
      color: '#8013D7',
    },
  ]

그리고 settings을 바꿔주시고, list배열을 map함수를 사용하여 화면에 출력하였습니다.

simpleSlider.js

....
var settings = {
    dots: true,
    centerMode: true,
    infinite: true,
    slidesToShow: 3,
    slidesToScroll: 1,
    swipeToSlide: true,
  };
  return (
    <SliderContainer>
      <Slider {...settings}>
        {list.map((value, index) => (
          <SliderContent
            $color={value.color}
            key={index}>
            {value.content}
          </SliderContent>
        ))}
      </Slider>
    </SliderContainer>
  );

style.js

export const SliderContent = styled.div`
    height: 300px;
    color: white;
    font-size: 100px;
    text-align : center;
    background-color: ${props => props.$color};
`

중간점검

현재 결과물입니다.
이제 컨텐츠 사이의 간격만 벌려주면 완성입니다.


슬라이더 사이 간격 조절

사실 이 부분에서 정말 많이 헤맸습니다. marginpadding으로 간격을 조절하면 슬라이더가 움직이는 간격이 일치하지 않아서 이 방법은 사용할 수 없었습니다. 그러다 찾은 방법이 바로 라이브러리 css의 .slick-list을 조절하는 것이었습니다.


먼저, 최상단에서 슬라이더를 감싸주는 div를 하나 만들어줍니다.

style.js

export const BodyContainer = styled.div`
    display: flex;
    position: relative;
    flex-direction: column;
    align-items: center;
    overflow: hidden;
`

그리고 슬라이더의 부모 컴포넌트에서 .slick-listwidth를 조절해줍니다.
슬라이더 컨텐츠의 width도 적절히 조절해주고 margin: auto를 해줍니다.

style.js

export const SliderContainer = styled.div`
    ...
    .slick-list{ 
        width: 4000px;
    }   
`

export const SliderContent = styled.div`
	...
    width: 1000px;
    margin: auto;
`

마지막으로 슬라이더 컨텐츠 컴포넌트를 div로 감싸주면 끝입니다.

simpleSlider.js

...
return (
    <BodyContainer>			// 최상단에서 슬라이더 감싸주기
      <SliderContainer>
        <Slider {...settings}>
          {list.map((value, index) => (
            <div>			// div로 컨텐츠 컴포넌트 감싸주기
              <SliderContent
                $color={value.color}
                key={index}>
                {value.content}
              </SliderContent>
            </div>
          ))}
        </Slider>
      </SliderContainer>
    </BodyContainer>
  );

결과 화면

전체코드

simpleSlider.js

import React from "react";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";

import {
  SliderContainer,
  BodyContainer,
  SliderContent,
} from './style'

export default function SimpleSlider() {
  const list = [
    {
      content: 1,
      color: '#FF5757',
    },
    {
      content: 2,
      color: '#FFBC57',
    },
    {
      content: 3,
      color: '#FFEE57',
    },
    {
      content: 4,
      color: '#57FF86',
    },
    {
      content: 5,
      color: '#5786FF',
    },
    {
      content: 6,
      color: '#8013D7',
    },
  ]

  var settings = {
    dots: true,
    centerMode: true,
    infinite: true,
    slidesToShow: 3,
    slidesToScroll: 1,
    swipeToSlide: true,
  };
  return (
    <BodyContainer>
      <SliderContainer>
        <Slider {...settings}>
          {list.map((value, index) => (
            <div>
              <SliderContent
                $color={value.color}
                key={index}>
                {value.content}
              </SliderContent>
            </div>
          ))}
        </Slider>
      </SliderContainer>
    </BodyContainer>
  );
}

style.js

import styled from 'styled-components';
import arrow from './images/right.png'

export const BodyContainer = styled.div`
    display: flex;
    position: relative;
    flex-direction: column;
    align-items: center;
    overflow: hidden;
`

export const SliderContainer = styled.div`
    margin: 200px 200px;
    .slick-prev:before,
    .slick-next:before {
        display: none;	
    }
    .slick-list{ 
        width: 4000px;
    }   
`

export const SliderContent = styled.div`
    height: 500px;
    color: white;
    font-size: 100px;
    line-height : 500px;
    text-align : center;
    background-color: ${props => props.$color};
    width: 1000px;
    margin: auto;
`

원리

개발자 도구로 슬라이더를 까보면 대충 이런 모습입니다.

여기서 슬라이더의 컨텐츠 하나의 width1334px인걸 볼 수 있습니다.
width가 어디서 나온것이냐 하면,

//(style.js)
export const SliderContainer = styled.div`
	...
    .slick-list{ 
        width: 4000px;
    }   
`

.slick-listwidth4000px

//(simpleSlider.js)
var settings = {
    ...
    slidesToShow: 3,
    ...
  };

slidesToShow3으로 나눈 값 입니다. (4000 / 3 = 1333.333...)

정리하자면, 슬라이더를 보여주는 컨테이너(.slick-list) 안에서 3개의 슬라이드(slidesToShow: 3)를 보여주고 싶기 때문에 슬라이더의 컨텐츠 하나의 width1334px이 된것입니다.


이런 역할을 하는 놈이 바로 react-slickSlider입니다. Slider는 위와 같은 계산 과정을 거친 후, 자식 컴포넌트의 width를 고정시켜버립니다. 따라서 슬라이더 컨텐츠 컴포넌트를 div로 감싸주었습니다.

import Slider from "react-slick";

...

  <Slider {...settings}>		//Slider는 자식의 width를 고정시켜버림
          {list.map((value, index) => (
            <div>  				//따라서 div로 SliderContent를 한번 감싸줌 -> div의 width: 1334px 고정
              <SliderContent
                $color={value.color}
                key={index}>
                {value.content}
              </SliderContent>
            </div>
          ))}
  </Slider>

width1334px로 고정된 div안에 width: 1000px, margin: auto를 준 슬라이더 컨텐츠 컴포넌트를 넣어줌으로써 슬라이더 사이 간격 조절을 할 수 있는것입니다!



5. 마치며

React-slick은 제가 프로젝트를 진행하면서 가장 자주 사용한 라이브러리입니다. 처음 이 라이브러리를 사용했을 때는 경고 메시지 투성이에 기본적인 슬라이더 하나 만들기도 힘들어했었지만, 그 당시에 하루 종일 시행착오를 겪으면서 얻은 경험이 최근에 회사 웹사이트를 제작할 때 정말 많은 도움이 되었습니다. 저번 프로젝트를 진행하며 얻은 지식과, 이번 웹사이트 제작 과정에서 새롭게 배운 지식들도 여기에 자세히 정리해 두었습니다. 이 정보가 다른 분들에게도 도움이 되기를 바라며, 모두 파이팅!!!

profile
Front-end 호소인

1개의 댓글

comment-user-thumbnail
2024년 4월 13일

good

답글 달기