본문 바로가기
  • 삽질하는 자의 블로그
React/React-Transition-Group

2. React Transition Group 의 기본 사용

by 이게뭐당가 2022. 12. 22.

1. 설치와 기능

npm install react-transition-group --save

React Transition Group 의 기본적인 기능은, 

[시작], [동작 중], [종료 시작], [종료 완료] 의 State 를 우리에게 제공하는 것이 전부이다.

우리는 거기에서 Transition 과 Animation 을 사용하여, 부드럽게 움직이는 애니메이션을 만들 수 있다.

 

React Transition Group 의 추가적인 기능으로는

1. 렌더 여부에 따라, 컴포넌트를 DOM 에서 제거할지, 말것인지 선택가능한 옵션들

2. 컴포넌트 자체를 애니메이션이 있는 컴포넌트로 만드는 기능들

3. 콜백함수를 사용하여, 동작중간에 함수를 동작하게 해주는 기능들

 

등이 있다.

 

 

2.  React Transition Group 의 기본적인 사용법

import { Transition } from "react-transition-group";
import { useState } from "react";
import "./App.css";

function App() {
    const [toggle, setToggle] = useState(false);

    const ptoggle = () => {
        setToggle((prev) => !prev);
        console.log(toggle);
    };

    return (
        <div className="App">
            <Transition in={toggle} timeout={500} unmountOnExit>
                {(state) => <h1 className={`fade-${state}`}>hi</h1>}
            </Transition>
        </div>
        );
    }

export default App;

설명!

 

        <Transition in={toggle} timeout={500} unmountOnExit>
            {(state) => <h1 className={`fade-${state}`}>hi</h1>}
        </Transition>

Transition 으로 JSX 코드를 감싸, 컴포넌트를 렌더한다.


		=======================================
    	<Transition in={toggle} timeout={500} unmountOnExit>
    
in 		= "렌더의 여부" 를 판단한다. false 가 기본 값이고, true 가 되면 감싼 코드를 실행한다.
timeout 	= "동작의 지속시간" 을 정한다. state가 바뀌는 시간을 의미한다.
unmountOnExit 	= [추가적인 옵션]중 하나이다. "렌더가 되지 않을때는 DOM 에서 제거한다"


		=======================================
	{(state) => <h1 className={`fade-${state}`}>hi</h1>}
    
state = "동작의 상태" 를 말한다.
    시작되면 : entering, entered, 
    종료하면 : exiting, exited
    를 반환한다.

다시말해,  시작되면, 클래스의 스타일이

   fade-entering   

   fade-entered   

종료하면, 클래스의 스타일이

   fade-exiting   

   fade-exited   

가 부여된다는 말이다.

그것을 토대로 CSS 스타일을 만든다.

.fade-entering {                    // 변화에 따른 세팅을 해준다
    opacity: 0.5;
    transition: all 300ms ease-in;  // transition 으로 부드럽게 만들어 줄 수 있다.
}
.fade-entered {                    // 변화에 따른 세팅을 해준다
    opacity: 1;
    transition: all 300ms ease-in;
}
.fade-exiting {                    // 변화에 따른 세팅을 해준다
    opacity: 0.8;
    transition: all 300ms ease-in;
}
.fade-exited {                    // 변화에 따른 세팅을 해준다
    opacity: 0;
    transition: all 300ms ease-in;
}

-   *** "글로벌 CSS 라서 사용 가능한 것"이다. 이대로는 module 형태로, [style.xxx] 형태로 사용 할 수 없다. ***

정말정말 중요한 점은, 이대로는 module 형태로, 스타일을 넣을 수가 없다.

module 형태로 스타일을 적용시키려고 정말 노력해 봤지만 안됐다

이것 때문에 정말 많이 헷갈렸다. 

결국은 글로벌 CSS ( import "/App.css" ) 를 사용하는 수 밖에 없었다.

 

3.  React Transition Group 의 실질적인 사용 - 모달 편

JSX 코드가 아니라 컴포넌트 자체를 렌더하는 방식

< App.js >
   
    import ModalM from "./components/modal-mine/modal-mine";
    import { Transition } from "react-transition-group";
    import { useState } from "react";

    function App() {
        const [modalOn, setModalOn] = useState(false);

        const onToggleModal = () => {
            setModalOn((prev) => !prev);
        };

        return (
            <div className="App">
                <Transition in={modalOn} timeout={1000} unmountOnExit mountOnEnter>    
                    {(state) => <ModalM state={state} onToggleModal={onToggleModal} />} // ModalM 을 렌더 
                </Transition>
                <div>
                    <button onClick={onToggleModal}> 토글 </button>
                </div>
            </div>
        );
    }

    export default App;
    
**  "unmountOnExit, mountOnEnter 두개의 옵션을 전부 넣어, DOM 에서도 깔끔하게 사라졌다가, 나타났다 하게"
** "키포인트는, 렌더를 할때 state 를 넘기는 것이다."

 

** 정말로 key 포인트는 state 를 넘기는것이다. 

    ** 결국 "Transition 의 역할"은, [state(시작, 가동중, 종료시작, 종료) 를 만들어 주는 것 뿐], 
    	그 "상태를 받아 내가 알아서 CSS 스타일을 적용"시키는데 있다. 

    즉, "Modal 컴포넌트" 에 "state" 와 "종료 함수(Toggle)"를 넘겨주어
    	"Modal.module.css" 에서 처리하게 만드는 것이다.

** 이렇게 컴포넌트 자체를 렌더하는 형식으로 한다면, module.css 를 적용 시킬 수 있다.

 

<Component / Modal.js >

    import styles from "./modal-mine.module.css";

    const ModalM = (props) => {
        const { onToggleModal } = props;                                      

        const stylesName = `${styles.content} ${styles[props.state]}`;     // state(시작,가동중,종료시작,종료) 를 받아옴
                                                                           //  그것으로 만든 [동적 styleName]
        return (
            <div>
                <div className={styles.backDrop}></div>
                <div className={stylesName}>                               // [동적 styleName] 적용
                    <h1> 모달 내거</h1>
                    <p> 이것은 모달 </p>
                    <button onClick={onToggleModal}> 종료하기</button>
                </div>
            </div>
        );
    };

    export default ModalM;

렌더될때 props 로 넘어 오는 것은, 스위치인 onToggleModal 뿐 아니라, props.state 가 넘어오게 된다.

 

props.state 는,  [entering], [entered],  [exiting], [exited] 4개의 String 으로, 이것을 이용해 클래스를 만든다.

 

여기서 잠깐!

 

className 의 여러개의 선택 방법

className 안에 " "로 된 String 값을 클래스 네임으로 넣는 방법

 

을 모른다면

https://dive-into-frontend.tistory.com/76 

 

6. className, style 다루기

리액트에서는 class 대신 className 을 사용한다. 또한 하나씩 지정할때에는, module.css 를 사용한다. .css 는 "전체 적용"을 불러오기에, .module.css 를 적극 활용하는 중이다. 사용하는 방법 몇가지를 알

dive-into-frontend.tistory.com

 

<CSS - MODAL>

    .backDrop {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(126, 126, 126, 0.656);
    }

    .content {
        position: absolute;
        text-align: center;
        padding: 2rem;
        width: 20rem;
        top: 35%;
        left: calc(50% - 10rem);
        background-color: beige;
    }

    .entering {                         // 각각의 [동적 style] 에 대한, CSS
        opacity: 0.5;
        transition: all 300ms ease-in;
    }
    .entered {                           // 각각의 [동적 style] 에 대한, CSS
        opacity: 1;
        transition: all 300ms ease-in;
    }
    .exiting {                           // 각각의 [동적 style] 에 대한, CSS
        opacity: 0.5;
        transform: scale(50%);
        transition: all 1000ms ease-in;
    }
    .exited {                           // 각각의 [동적 style] 에 대한, CSS
        opacity: 0;
        transform: scale(0);
        transition: all 300ms ease-in;
    }

이렇게 만들어두면, 동작할때, state 에 따라, 다른 className 이 들어가고, 

동작은 애니메이션 형태를 띄게 된다!

사라질때 까지도!

댓글