react transition group 으로 화면을 부드럽게 전환시키기

BinaryWoo_dev·2023년 7월 4일
0

style

목록 보기
3/3
post-thumbnail

서론


5월부터 시작한 사이드 프로젝트가 어느정도 마무리 단계에 접어들면서 개선할 부분을 찾아보다가 문득 화면 전환이 부드러워졌으면 좋겠다는 생각이 들었다.

그래서, 찾아본 몇 가지 방법들은 아래와 같다.

  1. motion-framer 라이브러리 사용
  2. react-transition-group 라이브러리 사용
  3. CSS3 의 Transition 사용

이 중에서 나는 2. react-transition-group 라이브러리를 사용하기로 하였다.

본론


React Transition Group 이란?

공식 문서 페이지에 따르면 React Transition Group 은 React-Motion 과 같은 애니메이션 라이브러리가 아니면 자체적으로 스타일을 애니메이션화하지 않는다고 한다. 대신 전환 단계를 노출하고 클래스 및 그룹 요소를 관리하여 유용한 방식으로 DOM 을 조작하여 실제 전환 효과 구현을 쉽게 만들 수 있도록 해준다고 한다.

설치

npm

npm install react-transition-group --save

yarn

yarn add react-transition-group

적용

TransitionGroup 및 Transition 컴포넌트 적용

화면 전환 효과를 적용할 페이지 컴포넌트를 <TransitionGroup/><Transition/> 으로 감싸주어야 한다.

나는 Next.js 환경에 react transition group을 적용할 것이기 때문에 /components/layout.tsx 에 적용하였다.

스타일 관련 설정

// /components/layout.tsx

const TIMEOUT = 100; // 전환 소요 시간 (ms)
const getTransitionStyles = {
	entering: { // status: 전환 중
		position: 'absolute',
		opacity: 0
	},
	entered: { // status: 전환 완료
		transition: `opacity ${TIMEOUT}ms ease-in-out, transform ${TIMEOUT}ms ease-in-out`,
		opacity: 1
	},
	exiting: { // status: 전환 시작 
		transition: `opacity ${TIMEOUT}ms ease-in-out, transform ${TIMEOUT}ms ease-in-out`,
		opacity: 0
	}
};

const Layout = ({ children }: IProps) => {...}

Transition 컴포넌트 적용하기

// /components/layout.tsx

import React, { ReactNode } from 'react';
import Header from './header';
import { useRouter } from 'next/router';
import { TransitionGroup, Transition } from 'react-transition-group';

interface IProps {
	children: ReactNode;
}
const TIMEOUT = 150;
const getTransitionStyles = {
	entering: {
		position: 'absolute',
		opacity: 0
	},
	entered: {
		transition: `opacity ${TIMEOUT}ms ease-in-out, transform ${TIMEOUT}ms ease-in-out`,
		opacity: 1
	},
	exiting: {
		transition: `opacity ${TIMEOUT}ms ease-in-out, transform ${TIMEOUT}ms ease-in-out`,
		opacity: 0
	}
};

const Layout = ({ children }: IProps) => {
	const router = useRouter();
	return (
		<div className='relative h-[100%]'>
			<Header />
+			<TransitionGroup style={{ position: 'relative' }}>
+				<Transition
					key={router.pathname}
					timeout={{
						enter: TIMEOUT,
						exit: TIMEOUT
					}}>
+					{(status) => (
+						<div
							style={{
								...getTransitionStyles[status]
							}}>
							<main>
								<div className='h-[100%] w-[100%] p-[2em] '>{children}</div>
							</main>
						</div>
					)}
				</Transition>
			</TransitionGroup>
		</div>
	);
};

export default Layout;

<Header/> 영역은 전환 효과를 주고 싶지 않았기 때문에, 페이지 컨텐츠 영역인 <main>...</main> 부분만 <Transition/> 으로 감싸주었다.

적용 결과 확인하기

적용 전

적용 후

결론


  • ☺️ CSS, 트랜지션, 애니메이션은 구현 단계는 머리 아플 수 있지만 완성하고 나면 UI에 훨씬 생동감이 느껴져서 기분이가 좋다.
  • 💡 추후 회사 솔루션 UI/UX 개선 프로젝트에도 해당 기능을 반영 제안해볼 예정이다.
profile
매일 0.1%씩 성장하는 Junior Web Front-end Developer 💻🔥

0개의 댓글