프로젝트를 진행하면서 뭔가 디자인적으로 밋밋한것 같아서 롤링되는 공지사항을 구현해보려고 한다.
먼저 공지사항 리스트를 받아와서 기본적인 틀을 잡아주자. 아직 데이터베이스와 연동하지 않아서 더미데이터를 활용하여 구현해보는 중이다.
import React from 'react'
const Notice = () => {
const notice = [
{
no: 1,
title: '뭐시깽이 도마뱀 입고',
content: '뭐시깽이 도마뱀 입고',
date: '2021-12-13 14:20:31'
},
{
no: 2,
title: 'SM GECKO 설 연휴 휴무 안내',
content: 'SM GECKO 설 연휴 휴무 안내',
date: '2021-12-13 14:20:31'
},
{
no: 3,
title: '뭐시깽이 도마뱀 입고',
content: '뭐시깽이 도마뱀 입고',
date: '2021-12-13 14:20:31'
},
{
no: 4,
title: '12월 SM GECKO 소식',
content: '12월 SM GECKO 소식',
date: '2021-12-13 14:20:31'
},
{
no: 5,
title: 'SM GECKO 운영 시간 알림',
content: 'SM GECKO 운영 시간 알림',
date: '2021-12-13 14:20:31'
},
]
return (
<ul className="notice">
<div style={{ transform: "translateY(-0px)" }}>
{notice.map((item, idx) => {
return (
<li className="notice_content" key={idx}>
<div>
<span className="notice_header">공지</span>
<div className="notice_title">{item['title']}</div>
</div>
</li>
)
})}
</div>
</ul>
)
}
export default Notice
ul
태그는 사용자가 확인할 수 있는 영역을, div
는 실제로 안에 들어가는 컨텐츠들을 움직이는 부분을, li
는 실제 컨텐츠를 담당한다.
먼저 ul 태그로 전체 틀을 잡아 준다. 미관상 좌우 여백을 padding
으로 잡아주었고 아래에 li
태그의 사이즈에 맞도록 높이를 70px
로, overflow
속성을 활용하여 ul태그 외부의 컨텐츠들을 숨겨주었다.
.notice{
padding: 0 40px;
height: 70px;
overflow: hidden;
}
공지사항이 들어갈 컨텐츠 부분을 30px
로 설정하였고 상하 padding
을 통하여 여백을 주었다. 그런 다음 line-height
속성으로 가운데 정렬해 주었다.
.notice_content {
height: 30px;
padding: 20px 0;
line-height: 30px;
}
여기까지 했으면 원하는대로 작동하는지 중간점검을 해보자.
개발자도구에서 div에 있는 인라인 스타일의 속성 transform 을 활용하여li
의 크기인 -70px
만큼 이동시켜보자
2번째 컨텐츠가 잘 보이는 것을 확인할 수 있다.
먼저 useState
, useEffect
, useRef
3가지 hooks 들을 사용하자
import React, { useState, useEffect, useRef } from 'react'
useEffect와 setInterval은 그렇게 잘 맞는 감성이 아니지만? 위에서 사용했던 3가지 hooks로 해결해보자.
const [idx, setIdx] = useState(0)
const idxRef = useRef(0)
...
useEffect(() => {
setInterval(() => {
idxRef.current = (idxRef.current + 1) % notice.length
setIdx(idxRef.current)
console.log(idxRef)
}, 2000)
}, [notice.length])
주의할 점은 useRef
를 사용하지 않고 state로만 처리하려고하면 첫 렌더링시에만 적용되고 먹통이 된다는 점이다. useRef를 통해 current값을 증가시키고 이를 state로 활용하자.
공지사항이 현재 5개만 들어가 있기 때문에 0~4까지 순환하는 것을 확인할 수 있다.
또한 애니메이션 효과를 주기 위하여 className
을 작성하자
<div className="notice_container" style={{ transform: `translateY(-${70 * idx}px)` }}>
...
</div>
.notice_container {
transition: transform 1s;
}