Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

짱이 될거야

React 페이지 전환 애니메이션 본문

프로젝트

React 페이지 전환 애니메이션

jeong57 2022. 8. 17. 11:40

1. 라이브러리 설치

npm install react-transition-group

공식문서: https://reactcommunity.org/react-transition-group/

 

React Transition Group

Exposes simple components useful for defining entering and exiting transitions. React Transition Group is not an animation library like React-Motion, it does not animate styles by itself. Instead it exposes transition stages, manages classes and group elem

reactcommunity.org

 

 

2. CSSTransition, TransitionGroup

Transition, CSSTransition, SwitchTransition, TransitionGroup 중 CSSTransition과 TransitionGroup을 사용한다.
  • CSSTransition: 애니메이션을 넣고자 하는 컴포넌트 윗 단에 불러오고, timeout(애니메이션 시간), classNames, onEnter 등을 적는다.
    • classNames: 구성 요소에 적용되는 애니메이션 className. (appear, appearActive, appearDone, enter, enterActive, enterDone, exit, exitActive, exitDone) / styles.css 파일을 만들어서 사용한다.
    • onEnter: 'enter' 또는 'appear' 클래스가 적용된 직후 발생하는 콜백.
    • onEntering: 'enter-active' 또는 'appear-active' 클래스가 적용된 직후 발생하는 콜백.
    • onEntered: 'enter' 또는 'appear' 클래스가 제거된 후 콜백.
    • onExit: 'exit' 클래스가 적용된 직후 콜백 발생.
    • onExiting: 'exit-active'가 적용된 직후 발생하는 콜백.
    • onExited: 'exit' 클래스가 제거되고 콜백 발생.
    • 참고: enter(마운트하기 시작할 때), enter-active(마운트 다했을 때), exit(언마운트 시작할 때), exit-active(언마운트 되고 난 후)
  • TransitionGroup: Transition, CSSTransition을 관리.

 

3. import

import { TransitionGroup, CSSTransition } from "react-transition-group";

 

4. 시행착오

현재 프로젝트 폴더 구조는 다음과 같다.

  • App.js
  • Router.js
  • index.js

index.js에서 App.js를 호출하고, App.js에서 Router.js를 호출한다.

Router.js는 아래 코드의 구조를 가지고 있다.

Router.js

import { BrowserRouter, Route, Routes } from "react-router-dom";

function Router() {
    return (
        <div>
            <BrowerRouter>
                <NavBar />
                <Routes>
                    <Route>
                    </Route>
                </Routes>
                <Footer />
            </BrowerRouter>
        </div>
    )
}

export default Router;

이 코드에 react-transition-group을 적용시켜 아래와 같이 만들었다.

import { BrowserRouter, Route, Routes, useLocation } from "react-router-dom";
import { TransitionGroup, CSSTransition } from "react-transition-group";

function Router() {
    const location = useLocation();

    return (
        <div>
            <BrowerRouter>
                <NavBar />
                <TransitionGroup>
                    <CSSTransition
                        key={location.pathname}
                        classNames="fade"
                        timeout={300}
                    >
                        <Routes location={location}>
                            <Route></Route>
                        </Routes>
                    </CSSTransition>
                </TransitionGroup>
                <Footer />
            </BrowerRouter>
        </div>
    )
}

export default Router;

이 때, CSSTransition에는 key값이 필요하고, Routes에 location을 넘겨줘야 한다. location은 "react-router-dom"의 useLocation을 호출해서 쓰는데 이 부분에서 계속해서 에러가 났다.

Uncaught&nbsp;Error:&nbsp;useLocation()&nbsp;may&nbsp;be&nbsp;used&nbsp;only&nbsp;in&nbsp;the&nbsp;context&nbsp;of&nbsp;a&nbsp;<Router>&nbsp;component.

현재 파일 위치에서 useLocation을 사용하면 안된다는 것 같았고, 구글링을 해봤다. 하지만 구글에 나온 코드들은 우리 프로젝트와 구조가 달랐는데, Router 안에서 App을 불러왔다.

그래서 다른 방법을 찾았고, 팀원의 조언을 바탕으로 TransitionGroup부터 Route 까지를 모아서 별도의 파일을 만든 후 import 시키기로 했다. 그 결과는 아래와 같다.

 

 

5. 결과

Router.js

import { BrowserRouter } from "react-router-dom";
import NavBar from "./components/Home/NavBar";
import Footer from "./components/Home/Footer";

import AnimationRouter from "./AnimationRouter";


function Router() {
  return (
    <div>
      <BrowserRouter>
        <NavBar />
        <AnimationRouter />
        <Footer />
      </BrowserRouter>
    </div>
  );
}

export default Router;

AnimationRouter.js

import "./styles.css"

import { useEffect } from "react";
import { Route, Routes, useLocation } from "react-router-dom";
import { TransitionGroup, CSSTransition } from "react-transition-group";


function AnimationRouter () {
  const location = useLocation();

  return (
    <TransitionGroup>
      <CSSTransition
        key={location.pathname}
        classNames="fade"
        timeout={300}
      >
        <Routes location={location}>
          <Route></Route>
          ...
        </Routes>
      </CSSTransition>
    </TransitionGroup>
  )
}

export default AnimationRouter;

styles.css

.fade-enter {
  opacity: 0.3;
}

.fade-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}

.fade-exit {
  opacity: 1;
}

.fade-exit-active {
  opacity: 0.3;
  transition: opacity 500ms ease-in;
}

 

6. 마무리

라우터 페이지에 애니메이션을 적용시키는 것은 생각보다 어렵지 않았다.

하지만 아직 react 사용법을 완전히 익히지 못해서 useLocation을 사용할 수 있는 파일 위치 등에서 오랜 시간이 걸렸다.

className이 아니라 classNames로 css를 사용하는 것과 enter, enter-active, exit, exit-active 등으로 나눠서 css를 줄 수 있다는 것이 새로웠다.

이제 애니메이션을 주는 데에는 성공했으니까 css를 조금 더 수정해봐야겠다.

Comments