Hyebin‘s blog

이번시간에는 Tab 기능을 만들어 볼 것이다.

 

탭 만들기

탭 디자인은 react-bootstrap 홈페이지에서 Base Nav를 사용하였다.

그리고 각각 탭을 누르면 <div></div> 로 몇번째 탭을 눌렀는지 state에 저장한 후 state에 따라 보여준다. 즉 이런 원리이다.

 

state가 0이면 0번 div를 보여줌

state가 1이면 1번 div를 보여줌

 

UI의 상태를 저장할 state를 만들어 준다.

 

(Detail.js)

function Detail(){

  let [누른탭, 누른탭변경] = useState(0);
  return (
    <div>
      <Nav variant="tabs" defaultActiveKey="link-0">
        <Nav.Item>
          <Nav.Link eventKey="link-0" onClick={()=>{ 누른탭변경(0) }}>Active</Nav.Link>
        </Nav.Item>
        <Nav.Item>
          <Nav.Link eventKey="link-1" onClick={()=>{ 누른탭변경(1) }}>Option 2</Nav.Link>
        </Nav.Item>
      </Nav>
      <div>내용0</div>
      <div>내용1</div>
      <div>내용2</div>
    
    </div>
  )
}

이제 if문으로 state의 현재상태에 따라 UI를 보여주면 된다.

하지만 문제는 삼항연산자는 if갯수가 늘어나면 사용하기 어렵다.

따라서 컴포넌트를 만들어 사용하는것이 효율적이다!

 

(Detail.js)

function Detail(){

  let [누른탭, 누른탭변경] = useState(0);
  return (
    <div>
      <Nav variant="tabs" defaultActiveKey="link-0">
        <Nav.Item>
          <Nav.Link eventKey="link-0" onClick={()=>{ 누른탭변경(0) }}>Active</Nav.Link>
        </Nav.Item>
        <Nav.Item>
          <Nav.Link eventKey="link-1" onClick={()=>{ 누른탭변경(1) }}>Option 2</Nav.Link>
        </Nav.Item>
      </Nav>
      <TabContent 누른탭={누른탭} />
    
    </div>
  )
}

function TabContent(props){
  if (props.누른탭 === 0){
    return <div>내용0</div>
  } else if (props.누른탭 === 1){
    return <div>내용1</div>
  } else if (props.누른탭 === 2){
    return <div>내용2</div>
  }
}

 

이렇게 컴포넌트를 만들고, 버튼을 누르면 탭 state를 변경해줬다.

이때 변경된 state가 0이면 0번째 div를 보여주고

변경된 state가 1이면 1번째 div를 보여준다.

변경함수 또한 props로 전달해 줘야 하기 때문에 <TabContent 누른탭={누른탭} />으로 props 전달한다.

 

애니메이션 부착하는 법

애니메이션은 HTML CSS짤 때와 똑같다. CSS파일에 코딩 후 className으로 부착한다. 부착할 때는

className={} 안에 삼항연산자를 사용하면 된다.

CSS스킬이 부족하면 라이브러리를 설치하는것도 좋다!

 

yarn add react-transition-group

npm install react-transition-group

설치 후 애니메이션 주고 싶은 컴포넌트 파일 상단 import 해온다.

 

import {CSSTransition} from 'react-transition-group';

1. <CSSTransition>으로 애니메이션 적용할 HTML들 감싼다.

2. 그리고 거기에 in, classNames, timeout 속성 넣는다.

 

(Detail.js)

function Detail(){
  return (
    <div>
      <CSSTransition in={true} classNames="wow" timeout={500}>
        <TabContent 누른탭={누른탭} />
      </CSSTransition>
    </div>
  )
}

function TabContent(){
  if (props.누른탭 === 0){
    return <div>내용0</div>
  } else if (props.누른탭 === 1){
    return <div>내용1</div>
  } else if (props.누른탭 === 2){
    return <div>내용2</div>
  }
}

 

in ? 간단하게 스위치 역할로 true일 때 애니메이션을 적용해준다.

classNames? 어떤 애니메이션을 적용할지 이름을 지정해준다.

timeout ? 작동시간이다.

 

3. CSS파일로 가서 애니메이션 코딩을 해준다.

(Detail.scss)

.wow-enter {
  opacity : 0
}

.wow-enter-active {
  opacity : 1;
  transition : all 500ms;
}

.작명-enter 라는 클래스명은 컴포넌트 등장시작시 적용할 CSS

.작명-enter-active 라는 클래스명은 컴포넌트 등장중일시 적용할 CSS

opacity : 0 , opacity : 1; 투명도를 0~1로 변경

transition은 서서히 변하게 해주세요~ 라는 속성

 

4. in={} 스위치 속성

스위치 속성은 처음에는 false로 해놨다가 필요할 때 true로 바꿔줘야한다.

(Detail.js)

function Detail(){
  
  let [스위치, 스위치변경] = useState(false);
  return (
    <div>
      <CSSTransition in={스위치} classNames="wow" timeout={500}>
        <TabContent 누른탭={누른탭} />
      </CSSTransition>
    </div>
  )
}

function TabContent(props){
  if (props.누른탭 === 0){
    return <div>내용0</div>
  } else if (props.누른탭 === 1){
    return <div>내용1</div>
  } else if (props.누른탭 === 2){
    return <div>내용2</div>
  }
}

in={스위치} 로 적용해주면 스위치가 true일때 애니메이션이 동작하고, 반대로 false이면 동작하지 않는다.

 

(Detail.js)

function Detail(){
  
  let [스위치, 스위치변경] = useState(false);
  return (
    <div>
      <Nav variant="tabs" defaultActiveKey="link-0">
        <Nav.Item>
          <Nav.Link eventKey="link-0" onClick={()=>{ 스위치변경(false); 누른탭변경(0) }}>Active</Nav.Link>
        </Nav.Item>
        <Nav.Item>
          <Nav.Link eventKey="link-1" onClick={()=>{ 스위치변경(false); 누른탭변경(1) }}>Option 2</Nav.Link>
        </Nav.Item>
      </Nav>
      <CSSTransition in={스위치} classNames="wow" timeout={500}>
        <TabContent 누른탭={누른탭} 스위치변경={스위치변경} />
      </CSSTransition>
    </div>
  )
}

function TabContent(props){

  useEffect( ()=>{
    props.스위치변경(true); //탭내용 컴포넌트가 로드될 때 true
  });

  if (props.누른탭 === 0){
    return <div>내용0</div>
  } else if (props.누른탭 === 1){
    return <div>내용1</div>
  } else if (props.누른탭 === 2){
    return <div>내용2</div>
  }
}

이러한 원리를 이용하여 버튼을 누르면 스위치는 false가 되고 탭 버튼이 업데이트 되면 true가된다.

 

정리

버튼을 누르면 스위치가 false가 되고 컴포넌트가 로드가 되면서 true가 된다.

true가 되면 작명한 컴포넌트의 애니메이션이 동작한다.

profile

Hyebin‘s blog

@hyebin Lee

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그