• 리액트에서 애니메이션 효과 구현하기

    2023. 7. 26.

    by. JJo 😊

    리액트 내에서도 CSS의 Transition과 Animation 속성을 이용하여 애니메이션을 구현할 수 있다. 

    하지만 상황에 따라 Animation 모듈을 이용하여 구현할수도 있다.

    🤔 React에서 animation 모듈을 사용하는 이유

    👉 UI가 화면에 보이지는 않지만 DOM에 존재한다.

    모달창의 UI를 애니메이션 효과를 주어 화면에 부드럽게 보이고 사라지는 모션을 주고자 할 때, display:none/block 속성은 애니메이션 효과를 줄 수 없기에 height나 opacity를 조절하여 모션을 준다.

    이 경우 화면상에는 보이지 않지만, HTML에는 존재하기 때문에 속도 저하나 접근성 면에서도 좋지 않다.

    👉 state가 변경되어 재랜더링 시, 애니메이션이 동작하지 않는 경우가 있다.

    state의 값에 따라 렌더링을 제어하는 경우, DOM에서 마운트나 언마운트되는 즉시 추가되거나 제거되기 때문에 해당 요소에 애니메이션이 적용되어 있어도 애니메이션 모션을 볼 수가 없다.


    이러한 이유로 리액트 애니메이션 관련 모듈인 React Transition Group을 사용하여 애니메이션 모션을 구현할 수 있다.

    😊 React Transition Group 시작하기

    // 설치
    npm install react-transition-group
    
    // 임포트
    import { Transition } from ‘react-transition-group’;

     

    React Transition Group에서는 몇가지 컴포넌트를 제공한다.

    각 컴포넌트의 특성을 살펴보고 이에 맞게 활용하면 쉽게 애니메이션을 제어할 수 있다.

    📌 Transition

    Transition 컴포넌트는 애니메이션의 전환이 일어날 때 4가지 상태 (entering, entered, exiting, exited)로 두어, 해당하는 전환 시점에 따라 컴포넌트를 조작할 수 있도록 도와주는 컴포넌트이다.

     

    state : entering → entered / exiting → exited로 상태가 반복 전환된다. 
    in : 애니메이션 스위치. 이를 통해 감싼 부분이 보일지 말지를 결정한다. 
    (in 속성 값이 true면 표출되고 false면 표출되지 않는다.)
    timeout은 애니메이션이 재생되는 시간(단위:ms)을 결정한다. 
    (entering에서 entered로, eixiting에서 exited로 전환할 때 걸리는 시간을 의미한다.)

    Transition에는 mountOnEnter, unmountOnExit속성이 있다. 
    mountOnEnter: lazy mount
    unmountOnExit: exiting이 끝나고 난 뒤 mount 해제
    그 외 여러 콜백 옵션을 제공한다. (onEnter, onEntering, onEntered, onExit, onExiting, onExited)

    아래 예시에서 콘솔창을 확인하면 콜백이 호출되는 시점을 확인할 수 있다.

     

     

    아래 소스는 state의 상태 변화에 다른 모달창 애니메이션을 추가한 예시이다.

     

    📌 CSSTransition

    CSSTransition 컴포넌트는 앞서 설명한 Transition의 모든 속성을 상속하며, 컴포넌트의 상태에 따른 CSS 속성을 부여하기 위해 사용된다. Transition과 다른 점은 Transition은 상태에만 관심이 있는 반면, CSSTransition은 상태에 따른 CSS 속성을 조금 더 쉽게 조작할 수 있다.

     

    상태에 따른 CSS 속성은 classNames에 지정한 이름으로 변환 상태가 자동으로 설정된다.

    예를 들어, classNames을 fade-modal로 지정하여면 변환 상태에 따라 fade-modal-enter, fade-modal-enter-active, fade-modal-exit, fade-modal-exit-active으로 fade-modal-변환상태 형식으로 클래스가 자동 부여된다.
    *-enter, *-exit는 초기 상태를 설정, *-active는 활성화된 상태를 제어한다고 생각하면 된다.

    이에 따라 알맞게 css를 추가하여 제어하면 된다.

    .fade-slide-enter {}
    .fade-slide-enter-active {animation: openModal 0.4s ease-out forwards;}
    
    .fade-slide-exit {}
    .fade-slide-exit-active {animation: closeModal 0.5s ease-out forwards;}

     

    👀 class 이름 사용자 정의하기

    classNames에서 설정한 이름을 기준으로 변환 상태 클래스가 확장되어 설정된다고 했는데, 때로는 이를 사용자 정의로 지정하고 싶은 경우가 있다.

    클래스 이름을 사용자 정의 하는 방법을 알아보자!

    classNames 속성 값으로 자바스크립트 객체를 전달할 수 있다. 이 객체에 다양한 css 클래스들을 수동으로 정의할 수 있다.

    const modal = (props) => {
      return (
        <CSSTransition
          in={props.show}
          timeout={animationTiming}
          mountOnEnter
          unmountOnExit
          classNames={{
            enter: '',
            enterActive: 'ModalOpen',
            exit: '',
            exitActive: 'ModalClosed',
            appear: '',
            appearActive: '',
          }}
        >
          <div className="Modal">
            <h1>A Modal</h1>
            <button className="Button" onClick={props.closed}>
              Dismiss
            </button>
          </div>
        </CSSTransition>
      );
    };

    📌 TransitionGroup

    여러 컴포넌트에게 CSSTransition을 적용시키고 싶을 때 CSSTransition들의 상위에 사용하는 컴포넌트이다. ol이나 ul, Routes 컴포넌트가 갖고 있는 각 리스트들에 전환 효과를 적용하고자 할 때 사용할 수 있으며, map함수와 같이 CSSTransition 각각에게 key값을 설정해주어야 한다.

    TransitionGroup는 기본적으로 div 태그로 렌더링되며, 이를 변경하고자 하는 경우 component 속성 값으로 ul이나 ol을 작성한다면 TransitionGroup 컴포넌트는 ul이나 ol 태그로 돔에 렌더링 되기 때문에 Content 영역에는 li 요소로 구성이 된다.

    TransitionGroup는 리스트에 전환 효과를 적용하기 위해서 사용 되므로 반드시 Transition이나 CSSTransition 컴포넌트와 함께 사용해야 한다.

     

    728x90

    'React' 카테고리의 다른 글

    React 컴포넌트에서 script 태그를 동적으로 삽입하기  (0) 2023.09.03
    모달창 외부 클릭 시 모달 닫기  (0) 2023.07.30
    useReducer, Context, Redux 차이  (0) 2022.11.16
    Jest  (0) 2022.11.10
    TDD  (0) 2022.11.10

    댓글