위코드 2차 프로젝트로 네이버 Expert 사이트 클론 중에 메인화면의 배너 슬라이더 구현 내용 정리하고자 합니다.
const BANNERS = [
{
no: 1,
image:
'https://ssl.pstatic.net/static/kin/09renewal/promotion/mobile/expert_promotion_banner_4_mobile20210615155941.jpg?ver=20210615035942',
title: '엑스퍼트 X KOTRA\n실시간 전문가\n상담 사업 신청 안내',
color: '#064689',
link: 'https://m.expert.naver.com/mobile/events/21024454906',
},
{
no: 2,
image:
'https://ssl.pstatic.net/static/kin/09renewal/promotion/mobile/expert_promotion_banner_4_mobile20210526165312.jpg?ver=20210526045312',
title: '영어공부를\n다시 시작한다면\n1:1 맞춤클래스',
color: '#035ac6',
link: '',
},
{
no: 3,
image:
'https://ssl.pstatic.net/static/kin/09renewal/promotion/mobile/expert_promotion_banner_4_mobile20210527100646.jpg?ver=20210527100646',
title: '무료한 일상\n솜씨당과 함께하는\n즐거운 취미 생활',
color: '#cc6a71',
link: '',
},
{
no: 4,
image:
'https://ssl.pstatic.net/static/kin/09renewal/promotion/mobile/expert_promotion_banner_4_mobile20210415171414.jpg?ver=20210415051415',
title: '요즘 핫한\n클래스만 모았어!\n90%할인 중',
color: '#4c7d19',
link: 'https://campaign.naver.com/eXpertTOPclass/?utm_source=naver&utm_medium=banner&utm_campaign=eXpertTOPclass_general&utm_content=experthome_general-hot_210415',
},
];
// import
import Slider from 'react-slick';
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';
...
// ref 추가
const slider = useRef();
...
// slick 설정
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
arrows: false,
};
...
// JSX 추가
<Slider ref={slider} {...settings}>
{BANNERS?.map((banner, i) => {
return (
<SwiperSlide key={i}>
<Link to={banner.link}>
<img alt={banner.title} src={banner.image} />
</Link>
</SwiperSlide>
);
})}
</Slider>
// /src/Hooks/useHook.js
import { useEffect, useRef } from 'react';
function useInterval(callback, delay) {
const savedCallback = useRef();
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
}
export default useInterval;
const [progressWidth, setProgressWidth] = useState(0);
...
useInterval(
() => {
if (progressWidth >= 100) {
setProgressWidth(0);
next();
} else {
setProgressWidth(progressWidth + 1 / (0.1 + 4));
}
},
isRunning ? 10 : null
);
// Next 슬라이드 Event
const next = () => {
setSlideIndex(slideIndex + 1 >= BANNERS.length ? 0 : slideIndex + 1);
setProgressWidth(0);
slider.current.slickNext();
};
// Prev 슬라이드 Event
const previous = () => {
setSlideIndex(slideIndex === 0 ? BANNERS.length - 1 : slideIndex - 1);
setProgressWidth(0);
slider.current.slickPrev();
};
const [isRunning, setIsRunning] = useState(true);
<PlayControlArea
onClick={() => {
setIsRunning(!isRunning);
}}
>
{isRunning ? (
<i className="fas fa-pause"></i>
) : (
<i className="fas fa-play"></i>
)}
</PlayControlArea>