리액트에서 SPA 형식으로 페이지를 이동하기 위해 react router
를 사용할 수 있다. 유저가 특정 액션을 취하면 페이지를 이동시킬 수 있고, 이 때 원하는 화면을 렌더링 할 수 있다. 오류 없이 동작한다면 기존 화면에서 새로운 화면으로 즉각 변환되는 것이다.
간단한 게임 웹앱을 개발하던 중 페이지가 넘어갈 때 "즉각" 넘어가는 것보다는 자연스럽고 부드럽게 페이지를 넘길 수 있는 방법이 없을까 고민하게 되었다. 아무래도 게임이다보니 부드러운 페이지 이동이 UX를 향상시킬 수 있을 것이란 기대감 때문이었다. 리액트 공식 라이브러리인 react-transition-group
을 사용하면 이 점을 개선시킬 수 있다는 것을 알게되었다.
이 라이브러리를 사용하면 모든 페이지에 transition을 줄 수도 있고, 특정 페이지에만 transition을 줄 수도 있다. 이 글에서는 간단하게 모든 페이지에 transition을 주는 방법까지만 기록할 예정이다.
모든 페이지에 transition을 주는 것은 꽤나 간단하다. component들을 라우팅해주는 Switch문을 감싸주고 렌더링해주면 된다. (하지만 처음 라이브러리를 공부하고 적용해서 원하는 결과를 얻기까지는 꽤 오랜 시간이 걸렸다...!)
// 기존 즉각 페이지 이동 코드
import { Switch, BrowserRouter, Route } from 'react';
const App = () => {
return (
<BrowserRouter>
<Switch>
<Route path="/" component={Index} />
<Route path="/main" component={Main} />
</Switch>
</BrowserRouter>
);
}
// react-transition-group을 사용한 코드
import { Switch, BrowserRouter, Route } from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import './App.css';
const App = () => {
return (
<BrowserRouter>
<Route render={({ location }) => {
return (
<TransitionGroup className="transition-group">
<CSSTranstion key={location.pathname} timeout={300} className="transition">
<Switch>
<Route path="/" component={Index} />
<Route path="/main" component={Main} />
</Switch>
</CSSTransition>
</TransitionGroup>
);
}}
</BrowserRouter>
);
}
CSSTransition
태그의 key
는 transition의 적용 조건이다. location
은 window
객체의 location
속성이고, pathname
은 url 뒤 path
를 뜻한다. 즉, 현재 url의 path
가 변경되면 transition을 적용시키는 것이고, 쉽게 얘기하면 Route
의 path
가 변경되면 (=페이지 이동이 필요할 경우가 되면) transition 애니메이션이 실행된다는 것이다.
timeout
은 className
transition의 css를 주어진 시간만큼 지속한다는 뜻이다.
transition 애니메이션을 적용시키기 위해서는 위 TransitionGroup
, CSSTransition
태그에 CSS 속성을 적용시켜주어야 한다. 공식 문서에 설명되어있는 것과 같이, CSSTransition
태그의 className
뒤에 enter
, enter-active
, exit
, exit-active
등을 붙여서 사용한다.
// App.css
.page-slider-enter {
opacity: 0.01;
}
.page-slider-enter.page-slider-enter-active {
opacity: 1;
transition: opacity 300ms ease-in;
}
.page-slider-exit {
opacity: 1;
}
.page-slider-exit.page-slider-exit-active {
opacity: 0.01;
}
.transition-group {
position: relative;
background-color: #000;
}
위 css 코드는 페이지를 부드럽게 넘길 수 있는 간단한 예제 코드 중 하나다. LRUD 중 하나의 방향에서 화면을 날아오게 만들 수도 있고, 기존 페이지 위에 다른 페이지가 날아와 덮는 형식의 transition을 줄 수도 있다.