css 애니메이션을 만들고 싶으면
- 애니메이션 동작 전 스타일을 담을 className 만들기
- 애니메이션 동작 후 스타일을 담을 className 만들기
- transition 속성도 추가
- 원할 때 2번 탈부착
탭의 내용이 서서히 등장하는 fade in 애니메이션을 만들어보겠습니다.
1. 애니메이션 동작 전 2. 애니매이션 동작 후 className만들기
CSS파일을 열어 다음과 같이 작성합니다.
애니메이션 동작 전엔 투명도가 0, 동작 후엔 투명도가 1이 됩니다.
.start {
opacity : 0
}
.end {
opacity : 1;
}
3. transtion 추가
transition은 "해당 속성이 변할 때 서서히 변경해주세요~"라는 뜻입니다.
그럼 이제 원하는 <div>요소에 start 넣어두고 end를 탈부착할 때마다 fade in이 됩니다.
.start {
opacity : 0
}
.end {
opacity : 1;
transition : opacity 0.5s;
}
end라는 className을 떼었다가 붙여보면 진짜로 애니메이션이 동작합니다.
function TabContent({number}){
return (
<div className="start end">
{ [<div>내용0</div>, <div>내용1</div>, <div>내용2</div>][number] }
</div>
)
}
4.원할 때 end 부착
이제 "버튼을 누를 때 마다 end를 저기 부착해주세요"라고 코드를 짜면 애니메이션 동작합니다.
버튼누르면 end부착하라고 코드짜려면 코드를 3번이나 짜야합니다(버튼이 3개라서)
그게 싫으면 useEffect를 사용해도됩니다.
useEffect를 쓰면 특정 state가 아니면 props가 변할 때 마다 코드실행이 가능하다고 했습니다.
그래서 "number라는 state가 변할 때 end를 저기 부착해주세요"라고 코드를 작성하면됩니다.
function TabContent({number}){
let [fade, setFade] = useState('')
useEffect(()=>{
setFade('end')
}, [number])
return (
<div className={'start ' + fade}>
{ [<div>내용0</div>, <div>내용1</div>, <div>내용2</div>][number] }
</div>
)
}
number라는게 변할 때 end를 저기 부착하고 싶으면 동적인 ui만드는 법을 떠올리면 됩니다.
- fade라는 state하나 만들고
- state에 따라서 className이 어떻게 보일지 작성
- 원할 때 fade를 변경
이제 number라는 state가 변할 때 마다 fade라는 state가 'end'로 변하고 className="start end"이렇게 변합니다.
하지만 위와같이 작성해도 애니메이션이 잘 보이지 않습니다.
end라는 클래스명을 부착하는게 맞긴 맞는데 end를 떼었다가 붙여야 잘 작동합니다.
그래서 clean up function안에 fade라는 state를 공백으로 바꾸라고 했으니
useEffect 실행전엔 'end'가 ''이걸로 바뀝니다.
function TabContent({number})
{
let [fade,setFade] = useState('');
useEffect(()=>{
setTimeout(()=>{ setFade('end') },100)
return()=>{
setFade('')
}
}, [number])
return <div className={'start '+ fade}>
{[ <div>내용0</div>, <div>내용1</div>, <div>내용2</div>][number]}
</div>
}
setTimeout을 왜쓰냐면
리액트 18 버전 이상부터는 automatic batch라는 기능이 생겼습니다.
state변경함수들이 연달아서 여러개 처리되어야 한다면 state변경함수를 다 처리하고 마지막에 한번만 재렌더링됩니다.
그래서 'end'로 변경하는거랑 '' 이걸로 변경하는거랑 약간 시간차를 뒀습니다.
응용
그래서 오늘 배운내용으로 컴포넌트페이지를 로드할 때 투명도가 0에서 1로 서서히 증가하는 애니메이션을 주려면?
아래와 같이 작성하면됩니다.
state는 위에서는 number를 사용했었는데 여기서는 페이지가 로드될때 애니메이션 효과를 줘야 하기 때문에 useParams()를 사용하여 id를 사용하면됩니다.
( 현재 /:url파라미터 자리에 유저가 입력한 값을 가져올 수 있습니다, /deatil/1로 접속하면 id라는 변수에 1이 들어옵니다.)
function DetailPage(props) {
let { id} = useParams();
let [fade,setFade] = useState('');
useEffect(()=>{
setTimeout(()=>{ setFade('end') },100)
return()=>{
setFade('')
}
}, [id])
return (
<div className={'start '+fade}>
아니면 id를 사용하지 않고 그냥 [] 만사용해도 됩니다. 그러면 컴포넌트 mount(로드시) 1회만 실행가능하기 때문입니다.
결과
'프론트엔드 > react' 카테고리의 다른 글
React - Redux(1) (0) | 2023.08.04 |
---|---|
React - Context API (0) | 2023.08.04 |
React - 리액트에서 탭 UI 만들기 (0) | 2023.08.04 |
React - ajax (0) | 2023.08.04 |
React - Lifecycle과 useEffect 2 (0) | 2023.08.01 |