탭 UI
버튼 3개와 박스 3개를 미리 만들어 놓고 버튼 누를 때마다 그에 맞는 박스를 보여주는UI
탭 UI 만들기
1. HTML, CSS로 디자인 미리 완성하기
2. UI의 현재 상태를 저장할 state 하나 만들기
3. state에 따라서 UI가 어떻게 보일지 작성하기
참고사항: 자식 컴포넌트에서 props 쉽게 쓰고 싶다면
function TabContent(porps){
return [ <div>내용0</div>, <div>내용1</div>, <div>내용2</div> ][props.tab]
}
▼ ▼ ▼
function TabContent({tab}){
return [ <div>내용0</div>, <div>내용1</div>, <div>내용2</div> ][tab]
}
자식 컴포넌트에서 props라고 파라미터를 하나만 작명하는 게 아니라 {state1이름, state2이름...} 이렇게 작성하면 props.state1.이름 이렇게 쓰지 않아도 된다.
컴포넌트 전환 애니메이션 주는 법(transition)
컴포넌트 등장, 퇴장 애니메이션이 필요하면 라이브러리를 설치해서 사용해도 되지만 간단한 건 CSS를 활용해서 개발이 가능하다. useEffect를 활용하면 된다.
애니메이션 만들고 싶으면
1. 애니메이션 동작 전 스타일 담은 className 만들기
2. 애니메이션 동작 후 스타일 담은 className 만들기
3. tranisiton 속성 추가
4. 원할 때 2번 탈부착
Detail 컴포넌트 로드시 투명도가 0에서 1로 서서히 증가하는 애니메이션을 만들어 보자.
1. 애니메이션 동작 전 스타일 담은 className 만들기,
2. 애니메이션 동작 후 스타일 담은 className 만들기
.start {opacity: 0;}
.end {opacity: 1;}
css 파일에 애니메이션 동작 전에 투명도가 0, 동작 후엔 투명도가 1이 되게 코드를 추가한다.
2. transition 추가
.start {opacity: 0;}
.end {opacity: 1;transition: opacity 0.5s;}
이제 원하는 <div> 요소에 start 넣어두고 end를 탈부착할 때마다 fade in이 된다.
(Detail.js)
function Detail(props){
return (
<Container className='start end'>
(하단 html 생략)
)
}
export default Detail
end라는 className을 떼었다가 붙여보면 애니메이션이 동작한다.
4. 원할 때 end 부착
Detail 컴포넌트 로드시에는 'end'를 부착, Detail 컴포넌트 삭제시에는 'end' 떼기
라고 코드를 작성했다.
(Detail.js)
function Detail(props){
let [detFade, setDetFade] = useState('');
useEffect(()=>{
setDetFade('end')
}, [])
return (
<Container className={"start " + detFade}>
(하단 html 생략)
)
}
export default Detail
이제 detFade이라는 state가 변할 때마다 fade라는 state는 'end'로 변하고 그러면 className="start end"이렇게 변한다.
버튼을 누르면 end가 부착되니까 애니메이션이 잘 보인다. 안 보임.
이유는 개발자 도구에서 검사해 보면 된다. end라는 클래스명을 부착하는 게 맞는데, 사실은 떼었다가 붙여야 애니메이션이 보인다. end를 떼었다가 다시 붙이면 작동한다.
(Detail.js)
function Detail(props){
let [detFade, setDetFade] = useState('');
useEffect(()=>{
setDetFade('end')
return () => {
setDetFade('');
}
}, [])
return (
<Container className={"start " + detFade}>
(하단 html 생략)
)
}
export default Detail
떼었다가 부착하라고 코드를 작성해 보았다.
clean up function 안에 fade라는 state를 공백으로 바꾸라고 했으니 useEfeect 실행 전엔 'end'가 ' ' 이걸로 바뀐다.
(+) setTimeout 쓰는 이유
리액트 18버전 이상부터는 automatic batch라는 기능이 생겼다.
state 변경 함수들이 연달아서 여러개가 처리되어야 한다면 state 변경 함수를 다 처리하고 마지막에 한 번만 재렌더링 된다. 그래서 'end'로 변경하는 거랑 ' '로 변경하는 거를 약간 시간차를 둔 것.
flushSync()를 써도 automatic batching 막아 준다.
* 이 포스팅은 코딩애플 강의를 토대로 작성하였습니다.