쇼핑몰 프로젝트(Tab 기능 / react-transition-group)

코딩애플 님의 강의를 바탕으로한 글입니다:)

Tab기능 만들기

이전에 쌩자바스크립트로 각각 다른 tab키를 눌렀을때 다른 div가 나오게 하느라고 애먹은 기억이 있다. 제이쿼리도 써보고, 템플릿도 사용했던 기억이 있는데, 드디어 오늘 리엑트를 공부하며 원리를 배워볼 수 있었다.

  1. 우선 리엑트 부트스트랩에서 원하는 탭 기능을 가져오자.
    이때 import 해서 해당 태그를 불러오는 것 잊지말자.
import {Nav} from 'react-bootstrap'
<Nav variant="tabs" defaultActiveKey="/home">
  <Nav.Item>
    <Nav.Link href="/home">Active</Nav.Link>
  </Nav.Item>
  <Nav.Item>
    <Nav.Link eventKey="link-1">Option 2</Nav.Link>
  </Nav.Item>
  <Nav.Item>
    <Nav.Link eventKey="disabled" disabled>
      Disabled
    </Nav.Link>
  </Nav.Item>
</Nav>
  1. 필요없는 href는 없애고 각자 key 값을 설정해주자.
  2. 이제 꽤 원리를 알 수 있는데, state(탭)를 만들어 클릭시 state이 변하게 하고(탭변경함수), 변한 값과 일치할 시 출력할 div를 설정하면 된다.
    let [탭, 탭변경] = useState(0);
  1. 삼항조건의 경우 많은 조건들이 들어오면 작성에 불편함이 있어, 컴포넌트를 새로 만들고 그 안에 if문을 통해 return문으로 div를 반환해준다. 이때 상위 컴포넌트에서 탭이라는 state값을 가져오는 것이니 props 잊지 말자.
function TabContent(props){
    useEffect(()=>{
      props.효과변경(true);
    })
    if(props.탭 === 0) {
        return <div>0번째</div>
     }
     else if(props.탭 === 1) {
      return <div>1번째</div>
     }
  }
  1. 각각 탭에는 onClick기능으로 콜백함수인 탭변경함수를 통해 state값을 탭에 맞게 설정한다.
  <Nav className="mt-5" 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>

정리) 각각 탭을 누를때 선언해놓은 state값이 변경이 되고, 따로 만들어놓은 컴포넌트 안에 조건문을 통해 변경된 state값과 일치할 경우 그에 맞는 div값이 출력되게 만들어보았다.

만약 탭을 누르고 출력되는 div에 CSS 효과를 주고 싶다면?
컴포넌트 등장/업데이트(useEffect()사용)할 경우 className을 부착하면 된다.
그리고 클릭 시에만 효과가 나타나야하므로 조건문을 통해 className을 호출(?)해야 한다.

하지만, 이러한 과정을 쉽게?는 아니고, 내 입장에서는 쉽게 다가갈 수 있는 방법이 있다.

eact-transition-group

  1. 설치
yarn add react-transition-group 또는 npm install react-transition-group
  1. 상단에 import
import {CSSTransition} from 'react-transition-group';
  1. CSSTransition을 통해 앞서 만든 탭 컴포넌트를 감싼다.
<CSSTransition>
        <TabContent 누른탭={누른탭} />
</CSSTransition>
  1. in, classNames, timeout 속성을 넣어준다.
  • in: 스위치와 같은 역할, true일 경우 애니매이션을 적용해주는 부분
  • classNames: 작명해주는 부분
  • timeout: 작동시간을 나타내는 부분
<CSSTransition in={true} classNames="wow" timeout={500}>
        <TabContent 누른탭={누른탭} />
</CSSTransition>
  1. 아까 작명한 wow라는 애니메이션의 작동방식/정의를 내려주자.
  • .작명-enter 라는 클래스명은 컴포넌트 등장시작시 적용할 CSS
  • .작명-enter-active 라는 클래스명은 컴포넌트 등장중일시 적용할 CSS.
(Detail.scss)
.wow-enter {
  opacity : 0
}
.wow-enter-active {
  opacity : 1;
  transition : all 500ms;
}
  1. 애니메이션이 항상 동작하는 것이 아니라 클릭 시 동작해야하므로 초기값은 false로 설정해주어야 한다. 따라서, 항상 하듯이 state를 선언하여 스위치기능을 만들어주자.
  let [스위치, 스위치변경] = useState(false);
  1. 탭의 버튼을 눌렀을 때 탭(스위치)이 false가 되게 만들어주자.
<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>
  1. 그리고 이를 true로 바꿔주면 되는데, 처음엔 일반적으로 클릭시 true로 변환되는 조건문을 생각했지만, 이제 useEffect() 훅을 알고 있다. 이 함수를 사용하면 컴포넌트가 실행시, 업데이트 시에 함수 속 선언된 코드가 실행이 된다. 따라서 스위치변경함수를 콜백함수로 하여 true로 바꾸어주는 것이다. 이때도 props를 통해 스위치변경함수를 가져다쓰는 것 잊지말자.
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>
  }
}

좋은 웹페이지 즐겨찾기