[React] react-transition-group :: 마이구미
이 글은 트랜지션과 관련된 라이브러리 react-transition-group 을 다룬다.
조금이나마 도움을 줄 수 있는 라이브러리들을 소개하는 카테고리로 분류된 글이다.
알아두면 좋은 라이브러리
react-transition-group 는 굉장히 심플하다.
게다가 이미 공식 문서에서는 기본적인 예제는 codesandbox 를 통해 제공해주고 있어, 크게 설명할 게 없다.
처음 접한다면 공식 문서를 한번 훑고 오는걸 추천한다.
이 글의 핵심은 기본 예제가 아닌 좀 더 응용할 수 있는 예제를 다뤄본다.
응용 예제는 라이브러리에서 제공해주는 TransitionGroup 컴포넌트를 주로 다루는 예제가 된다.
우선 간단하게 라이브러리를 알아보자.
진입(entering), 후퇴(exiting) 라는 용어로 트랜지션이 관리된다.
라이브러리는 진입과 후퇴과 관련된 시점을 제공해주어, 그것을 우리는 활용하게 된다.
크게 다음과 같은 상태가 있다고 보면 된다.
- entering
- entered
- exiting
- exited
css 로 나타나면 우리는 다음과 같이 정의하게 된다.
.my-node-enter {
opacity: 0;
}
.my-node-enter-active {
opacity: 1;
transition: opacity 200ms;
}
.my-node-exit {
opacity: 1;
}
.my-node-exit-active {
opacity: 0;
transition: opacity 200ms;
}
기본적인 예제는 다음 예제를 참고하면 된다.
그리고 react-router 와 함께 페이지 단위의 트랜지션을 원하는 경우에는 다음 예제를 참고할 수 있다.
페이지 트랜지션을 더 나아가 트랜지션 시점에 진입 페이지, 후퇴 페이지 모두 유지해보자.
즉, 이전 페이지가 사라지고 다음 페이지로 노출되는 것이 아닌, 서서히 이전 페이지와 다음 페이지가 함께 "진입" 및 "후퇴" 되는 것을 의미한다.
우선 1개가 아닌 2개의 컴포넌트에 대한 트랜지션을 요구하기 때문에 TransitionGroup 을 사용한다.
결국 TransitionGroup 내부에서 진입 컴포넌트와 후퇴 컴포넌트를 제어하는 의미가 된다.
이를 위해서는 Props 중 childFactory 를 활용한다.
<TransitionGroup
childFactory={(child) =>
React.cloneElement(child, { classNames: 'slide' })
}
>
<CSSTransition>
...
</CSSTransition>
</TransitionGroup>
childFactory 는 후퇴하는 컴포넌트를 업데이트할 수 있게 해준다.
위 코드처럼 컴포넌트에 트랜지션이 적용된 className 을 주입하는 모습을 볼 수 있다.
그리고 위와 같은 페이지 트랜지션 적용을 위해서는 react-router 쪽에서 한가지 해줘야한다.
<Routes location={location}>
...
</Routes>
Routes 컴포넌트에 location 을 넘겨줘야한다.
기본적으로 필요시 history.location 을 바라본다.
하지만 history.location 은 불변성을 띄지 않는다.
결국 항상 current location 을 바라보는 이슈로 진입, 후퇴 모두 동일한 페이지를 보게 된다.
location props 에 react-router 에서 제공하는 훅(useLocation)을 통해 제공한다면, 라이프사이클 훅 내부에서는 원하는 값을 보장할 수 있다.
응용 예제 1 - scale 트랜지션
응용 예제 1 - scale + slide 트랜지션
응용 예제는 이슈가 몇가지 존재하기 때문에 예제 관점으로 보길 바란다.
ex) 트랜지션이 필요한 route 를 Lazy import 하면 트랜지션 시점에 트랜지션 대상 컴포넌트를 찾지 못하는 이슈가 존재한다.
참고 자료
https://tech.lalilo.com/dynamic-transitions-with-react-router-and-react-transition-group
추가 자료
react-transition-group 내부에서 사용하는 trick - https://github.com/reactjs/react-transition-group/blob/5007303e729a74be66a21c3e2205e4916821524b/src/CSSTransition.js#L208-L215
파일 사이즈 비교 - https://bundlephobia.com/package/react-transition-group@4.4.1
npm trend - https://www.npmtrends.com/react-motion-vs-react-spring-vs-react-transition-group
https://tech.lalilo.com/dynamic-transitions-with-react-router-and-react-transition-group